Поймать несколько исключений в одной строке (кроме блока) - PullRequest
2377 голосов
/ 24 июня 2011

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

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

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

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

Ответы [ 5 ]

3220 голосов
/ 24 июня 2011

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

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

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

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

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

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

256 голосов
/ 21 июня 2014

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

Сделайте это:

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.

40 голосов
/ 30 октября 2014

С Документация Python -> 8.3 Обработка исключений :

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

except (RuntimeError, TypeError, NameError):
    pass

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

25 голосов
/ 18 сентября 2017

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

#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. Если вам также необходимо поймать другие исключения, кроме предварительно определенный кортеж, вам нужно определить другой, кроме блока.

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

10 голосов
/ 17 августа 2017

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

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]

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...