Питання Спробуйте кілька винятків в одному рядку (крім блоку)


Я знаю, що можу зробити:

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

Отже, моє прагнення спіймати дві чітко виняткові винятки точно не виходить.

Чи є спосіб зробити це?


1963
2018-06-24 15:55


походження




Відповіді:


Від Документація Python:

Наприклад, крім пункту, може бути назва декількох винятків, як, наприклад, круглий дубль

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Або лише для Python 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

Відокремлення винятку з змінної комою буде працювати в Python 2.6 та 2.7, але зараз він не підтримується та не працює в Python 3; тепер ви повинні використовувати as.


2712
2018-06-24 15:56



Чи можна зберігати бажані винятки в ітерабельному, а потім ловити ітерабельний? Я намагаюся перетворити список попереджень на використання помилок warnings.filterwarnings, і я не хочу, щоб він двічі вказав список попереджень. - BallpointBen
Я спробував це ... з a list, і це призвело до a TypeError. Схоже, помилки повинні бути в a tuple для лову, щоб працювати, як очікувалося. - BallpointBen
Чому б ви коли-небудь використовували список, коли ви чітко бачите, що документовано, що потрібний кортеж у цьому випадку? - bernie
Було незрозуміло, чи був "круглий стовпчик" просто синтаксичним або що потрібен справжній кортеж. "Пряме згортання" вводить в оману, оскільки ви можете створити кортеж без дужок в іншому місці, а потім використовувати його в exceptлінія Вона обов'язково вставляється в дужку, якщо вона створена в except лінія - BallpointBen


Як спіймати кілька винятків в одному рядку (крім блоку)

Зробити це:

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

Дужки потрібні через старший синтаксис, який використовував коми для призначення об'єкта помилки на ім'я. The 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 the 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 або вище, перейдіть на новий спосіб це зробити, щоб ваш код залишався сумісним під час оновлення.

The suppress менеджер контексту

Прийнята відповідь - це дійсно 4 рядки коду, мінімум:

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

The try, except, pass лінії можна обробляти в одній лінії з придушити менеджер контекстів, доступний у Python 3.4:

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

Отже, коли ти хочеш pass за певними винятками, використовувати suppress.


186
2018-06-21 04:20



Найбільш повна відповідь. Єдиний, який вказує, як використовувати except (KeyboardInterrupt, EOFError): синтаксис - Eduard Luca


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

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

Де e це екземпляр виключення.


49
2018-05-13 12:37



Ви не повинні призначати e за допомогою коми, якщо ви хочете отримати сумісний код вперед, а Python 2.5 більше не оновлюється: mail.python.org/pipermail/python-committers/2011-October... - Aaron Hall♦
так, але за допомогою python 2.5 іншого шляху немає. Рішення прямо визначає (стару) версію. - Jean-François Fabre


Від Документи Python -> 8.3 Обговорення винятків:

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

except (RuntimeError, TypeError, NameError):
    pass

Зауважте, що круглі дужки навколо цього кортежу потрібні, тому що   окрім ValueError, e: Синтаксис використовувався для звичайного   написано як except ValueError as e: в сучасному Python (описано   нижче) Старий синтаксис все ще підтримується для зворотної сумісності.   Це означає except RuntimeError, TypeError не є еквівалентом    except (RuntimeError, TypeError): але до except RuntimeError as TypeError: що не те, що ви хочете.


37
2017-10-30 10:01





Якщо ви часто використовуєте велику кількість винятків, ви можете попередньо визначити кортеж, тому вам не доведеться повторно вводити їх повторно.

#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 () і передати його навколо де потрібно ...


15
2017-09-18 01:36





Один із способів зробити це ..

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]

Я знаю, що другий - це не найкращий спосіб зробити це, але я просто показую кілька способів зробити це.


5
2017-08-17 11:56





Документація Python 2.7 зазначає, що:

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

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

Примітка   що круглі дужки навколо цього кортежу потрібні, тому що окрім   ValueError, e: був синтаксис, який використовується для того, що зазвичай записується як   за винятком ValueError як e: у сучасному Python (описано нижче). Старий   Синтаксис все ще підтримується для зворотної сумісності. Це означає   крім RuntimeError, TypeError не еквівалентний, крім   (RuntimeError, TypeError): але, крім RuntimeError як TypeError:   що не те, що ви хочете.


3
2017-12-05 14:05