Захват нескольких исключений в одной строке (кроме блока)

Я знаю, что могу сделать:

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

Я также могу это сделать:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

Но если я хочу сделать то же самое внутри двух разных исключений, лучшее, что я могу сейчас придумать, это сделать:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

Есть ли способ, которым я могу сделать что-то вроде этого (так как действие для обоих исключений - say please):

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

Теперь это действительно не сработает, поскольку он соответствует синтаксису для:

try:
    # do something that may fail
except Exception, e:
    # say please

Итак, мои усилия, чтобы поймать два разных исключения, точно не проходят.

Есть ли способ сделать это?

Ответ 1

От Документация на Python:

Предложение except может содержать несколько исключений в виде скобок в скобках, например

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Или, только для Python 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

Отключение исключения от переменной с помощью запятой будет по-прежнему работать в Python 2.6 и 2.7, но теперь устарело и не работает в Python 3; теперь вы должны использовать as.

Ответ 2

Как уловить несколько исключений в одной строке (кроме блока)

Сделай это:

try:
    may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
    handle(error) # might log or have some other default behavior...

Скобки необходимы из-за более старого синтаксиса, который использовал запятые для присвоения объекту ошибки имени. Ключевое слово as используется для назначения. Вы можете использовать любое имя для объекта ошибки, я предпочитаю error лично.

Лучшая практика

Чтобы сделать это в соответствии с текущей и будущей совместимостью с Python, вам нужно разделить Исключения с помощью запятых и обернуть их круглыми скобками, чтобы отличать от более раннего синтаксиса, который присваивал экземпляр исключения имени переменной, следуя типу исключений, который должен быть пойман с помощью запятая.

Вот пример простого использования:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    quit(0)

Я указываю только эти исключения, чтобы избежать скрытия ошибок, которые, если я столкнулся, я ожидаю от полной трассировки стека.

Это описано здесь: https://docs.python.org/tutorial/errors.html

Вы можете назначить исключение переменной, (e является общей, но вы можете предпочесть более подробную переменную, если у вас длительная обработка исключений, или ваша среда IDE выделяет только выделение, большее, чем это делает мой.) У экземпляра есть атрибут args. Вот пример:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError) as err: 
    print(err)
    print(err.args)
    quit(0)

Обратите внимание, что в Python 3 объект err выпадает из области действия, когда завершается блок except.

Устаревшие

Вы можете увидеть код, который присваивает ошибку запятую. Это использование, единственная форма, доступная в Python 2.5 и более ранних версиях, устарела, и если вы хотите, чтобы ваш код был совместим с переходом на Python 3, вы должны обновить синтаксис, чтобы использовать новую форму:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    quit(0)

Если вы видите назначение имени запятой в своей кодовой базе и используете Python 2.5 или выше, переключитесь на новый способ сделать это, чтобы ваш код оставался совместимым при обновлении.

Менеджер контекста suppress

Принятый ответ - это действительно 4 строки кода, минимум:

try:
    do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

try, except pass строк, может обрабатываться в одной строке с помощью диспетчера контекста подавления, доступного в Python 3.4:

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

Поэтому, когда вы хотите pass определенные исключения, используйте suppress.

Ответ 3

Для python 2.5 и более ранних версий правильный синтаксис:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

Где e - это экземпляр Exception.

Ответ 4

Из Документация по Python → 8.3 Обработка исключений:

Оператор try может иметь более одного исключения, чтобы указать обработчиков для разных исключений. Не более одного обработчика будет казнены. Обработчики обрабатывают исключения, которые происходят в соответствующее предложение try, а не в других обработчиках одной и той же попытки выражение. Предложение except может содержать несколько исключений в качестве в скобках, например:

except (RuntimeError, TypeError, NameError):
    pass

Обратите внимание, что круглые скобки вокруг этого кортежа необходимы, потому что кроме ValueError, e: был синтаксис, используемый для того, что обычно написанное как except ValueError as e: в современном Python (описано ниже). Старый синтаксис по-прежнему поддерживается для обратной совместимости. Это означает, что except RuntimeError, TypeError не эквивалентно except (RuntimeError, TypeError):, но до except RuntimeError as TypeError:, который не является тем, что вы хотите.

Ответ 5

Если вы часто используете большое количество исключений, вы можете предварительно определить кортеж, поэтому вам не нужно повторно вводить их много раз.

#This example code is a technique I use in a library that connects with websites to gather data

ConnectErrs  = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)

def connect(url, data):
    #do connection and return some data
    return(received_data)

def some_function(var_a, var_b, ...):
    try: o = connect(url, data)
    except ConnectErrs as e:
        #do the recovery stuff
    blah #do normal stuff you would do if no exception occurred

ПРИМЕЧАНИЯ:

  • Если вам также нужны другие исключения, кроме предопределенный кортеж, вам нужно будет определить другой, кроме блока.

  • Если вы просто не можете терпеть глобальную переменную, определите ее в main() и передать его там, где это необходимо...

Ответ 6

Один из способов сделать это:

try:
   You do your operations here;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   If there is any exception from the given exception list, 
   then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

а другой способ - создать метод, выполняющий задачу, выполняемую блоком except, и вызвать его через весь блок except, который вы пишете.

try:
   You do your operations here;
   ......................
except Exception1:
    functionname(parameterList)
except Exception2:
    functionname(parameterList)
except Exception3:
    functionname(parameterList)
else:
   If there is no exception then execute this block. 

def functionname( parameters ):
   //your task..
   return [expression]

Я знаю, что второй - это не лучший способ сделать это, но я просто показываю несколько способов сделать это.

Ответ 7

Python 2.7 Документация гласит, что:

Оператор try может иметь более одного предложения except, чтобы указать обработчиков для разных исключений. Не более одного обработчика будет казнены. Обработчики обрабатывают исключения, которые происходят в соответствующее предложение try, а не в других обработчиках одной и той же попытки выражение. Предложение except может содержать несколько исключений в качестве в скобках, например:

try:
    raise ValueError("hello")
except (RuntimeError, ValueError, KeyError) as a:
    print a

Примечание что круглые скобки вокруг этого кортежа необходимы, потому что кроме ValueError, e: был синтаксис, используемый для того, что обычно записывается как кроме ValueError как e: в современном Python (описано ниже). Старый синтаксис по-прежнему поддерживается для обратной совместимости. Это означает кроме RuntimeError, TypeError не эквивалентен исключению (RuntimeError, TypeError): но для исключения RuntimeError как TypeError: который не является тем, что вы хотите.