Вопрос-Ответ

How to catch multiple exceptions in one line? (in the "except" block)

Как перехватить несколько исключений в одной строке? (в блоке "except")

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

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...

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

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

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

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

import sys

try:
mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
sys.exit(0)

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

Это задокументировано здесь: https://docs.python.org/tutorial/errors.html

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

import sys

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

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

Устарело

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

import sys

try:
mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
print err
print err.args
sys.exit(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 -> 8.3 Обработка исключений:


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


except (RuntimeError, TypeError, NameError):
pass

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


Ответ 4

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

#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

Примечания:


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


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


2024-01-01 09:23 python