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


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

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

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

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


1912


источник


Ответы:


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

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

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

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

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

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


2640



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

Сделай это:

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

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

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

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

Вот пример простого использования: в настоящее время я обертываю mainв моей интерактивной командной строке PythonTrainer программы с уловкой для KeyboardInterrupt и EOFError, чтобы пользователь мог спокойно покинуть сеанс ввода интерактивной клавиатуры с помощью Ctrl + D или Ctrl + С :

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary for Python 3
    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,


178



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

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

где eявляется экземпляром Exception.


48



Из Документация 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:который не то, что вы хотите.


36



If you frequently use a large number of exceptions, you can pre-define a tuple, so you don't have to re-type them many times.

#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

NOTES:

  1. If you, also, need to catch other exceptions than those in the pre-defined tuple, you will need to define another except block.

  2. If you just cannot tolerate a global variable, define it in main() and pass it around where needed...


11



One of the way to do this is..

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. 

and another way is to create method which performs task executed by except block and call it through all of the except block that you write..

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]

I know that second one is not the best way to do this, but i'm just showing number of ways to do this thing.


4



Python 2.7 Documentation states that:

A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same try statement. An except clause may name multiple exceptions as a parenthesized tuple, for example:

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

Note that the parentheses around this tuple are required, because except ValueError, e: was the syntax used for what is normally written as except ValueError as e: in modern Python (described below). The old syntax is still supported for backwards compatibility. This means except RuntimeError, TypeError is not equivalent to except (RuntimeError, TypeError): but to except RuntimeError as TypeError: which is not what you want.


2