Захват нескольких исключений в одной строке (кроме блока)
Я знаю, что могу сделать:
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: который не является тем, что вы хотите.