Przechwytywanie wielu WYJĄTKÓW w jednej linii (z wyjątkiem bloku)

Wiem, że potrafię:

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

Mogę też to zrobić:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

Ale jeśli chcę zrobić to samo wewnątrz dwóch różnych WYJĄTKÓW, Najlepsze, o czym teraz myślę, to zrobić to:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

Czy Jest jakiś sposób, żebym mógł zrobić coś takiego (skoro akcja do podjęcia w obu wyjątkach to say please):

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

Teraz to naprawdę nie zadziała, ponieważ pasuje do składni dla:

try:
    # do something that may fail
except Exception, e:
    # say please

Więc, mój wysiłek, aby złapać dwa różne wyjątki nie do końca.

Jest na to jakiś sposób?
Author: inspectorG4dget, 2011-06-24

6 answers

From Dokumentacja Pythona :

Klauzula except może nazywać wiele wyjątków jako krotkę w nawiasie, na przykład

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Lub, tylko dla Pythona 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

Oddzielenie wyjątku od zmiennej przecinkiem nadal będzie działać w Pythonie 2.6 i 2.7, ale jest teraz przestarzałe i nie działa w Pythonie 3; Teraz powinieneś używać as.

 4095
Author: mechanical_meat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 13:56:48

Jak wyłapać wiele wyjątków w jednej linii (poza blokiem)

Zrób to:

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

Nawiasy są wymagane ze względu na starszą składnię, która używała przecinków do przypisania obiektu błędu do nazwy. Do przypisania używane jest słowo kluczowe as. Możesz użyć dowolnej nazwy dla obiektu błędu, ja osobiście wolę error.

Najlepsza Praktyka

Aby zrobić to w sposób aktualnie i do przodu zgodny z Pythonem, musisz oddzielić wyjątki za pomocą przecinków i zawiń je nawiasami, aby odróżnić je od wcześniejszej składni, która przypisywała instancję wyjątku do nazwy zmiennej, podążając za typem wyjątku, który ma zostać przechwycony za pomocą przecinka.

Oto przykład prostego użycia:
import sys

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

Podaję tylko te wyjątki, aby uniknąć ukrywania błędów, które jeśli napotkam, oczekuję pełnego śledzenia stosu.

Jest to udokumentowane tutaj: https://docs.python.org/tutorial/errors.html

Możesz przypisanie wyjątku do zmiennej, (e jest powszechne, ale możesz preferować bardziej szczegółową zmienną, jeśli masz długą obsługę wyjątków lub twój IDE podświetla tylko wybory większe niż to, jak moje.) Instancja posiada atrybut args. Oto przykład:

import sys

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

Zauważ, że w Pythonie 3 obiekt err wypada poza zakres, gdy blok except zostanie zakończony.

Deprecated

Możesz zobaczyć kod, który przypisuje błąd przecinkiem. To użycie, jedyna forma jeśli chcesz, aby Twój kod był zgodny z Pythonem 3, zaktualizuj składnię, aby użyć nowego formularza: {]}

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    sys.exit(0)

Jeśli widzisz przypisanie nazwy przecinka w bazie kodowej i używasz Pythona 2.5 lub nowszego, przełącz się na nowy sposób, aby Twój kod pozostał zgodny podczas aktualizacji.

The suppress context manager

Akceptowana odpowiedź to tak naprawdę 4 linijki kodu, minimum:

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

The try, except, pass linie mogą być obsługiwane w jednym wierszu za pomocą Menedżera kontekstu , dostępnego w Pythonie 3.4:

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

Więc jeśli chcesz pass na pewnych wyjątkach, użyj suppress.

 356
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-04 14:43:55

From dokumentacja Pythona - > 8.3 Obsługa wyjątków :

A try oświadczenie może mieć więcej niż jedną klauzulę, aby określić obsługa różnych WYJĄTKÓW. Co najwyżej jeden prowadzący będzie stracony. Handlery obsługują tylko wyjątki, które występują w odpowiadająca klauzula try, a nie w innych programach obsługujących tę samą próbę oświadczenie. Klauzula Exception może nazywać wiele wyjątków jako krotka w nawiasie, na przykład:

except (RuntimeError, TypeError, NameError):
    pass

Zauważ, że nawiasy wokół tej krotki są wymagane, ponieważ z tym, że ValueError, e: Była składnią używaną do tego, co zwykle napisane jako except ValueError as e: we współczesnym Pythonie (opisane poniżej). Stara składnia jest nadal obsługiwana dla zgodności wstecznej. Oznacza to, że except RuntimeError, TypeError nie jest równoważne except (RuntimeError, TypeError): ale do except RuntimeError as Co nie jest tym, czego chcesz.

 55
Author: fedorqui 'SO stop harming',
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-20 11:34:36

Jeśli często używasz dużej liczby WYJĄTKÓW, możesz wstępnie zdefiniować krotkę, więc nie musisz ich wpisywać wielokrotnie.

#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

Uwagi:

  1. Jeśli, również, trzeba złapać inne wyjątki niż te w wstępnie zdefiniowana krotka, będziesz musiał zdefiniować inny blok z wyjątkiem.

  2. Jeśli po prostu nie możesz tolerować zmiennej globalnej, zdefiniuj ją w głównym() i przekaż je tam, gdzie trzeba...

 42
Author: whitebeard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-18 01:36:57

Jednym ze sposobów na to jest..

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. 

A innym sposobem jest stworzenie metody, która wykonuje zadanie wykonywane przez except block i wywoła je przez cały except blok, który piszesz..

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]
Wiem, że ten drugi nie jest najlepszym sposobem na to, ale po prostu pokazuję wiele sposobów, aby to zrobić.
 19
Author: M.Usman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-17 11:56:07

Możemy to zrozumieć bardzo prosty przykład:-

import math
def square(x):
    if int(x) is 0:
        raise ValueError('Input argument cannot be zero')
    if int(x) < 0:
        raise TypeError('Input argument must be positive integer')
    return math.pow(int(x), 2)

W kodzie blokowym Exception jest to samo dla obu typów wyjątków. W takim przypadku możemy usunąć nadmiarowość kodu przekazując krotkę typów wyjątków w bloku Exception. Oto kod, w którym wyłapujemy wiele wyjątków w jednym bloku except.

while True:
    try:
        y = square(input('Please enter a number\n'))
        print(y)
    except (ValueError, TypeError) as e:
        print(type(e), '::', e)

Lub możemy powiedzieć, że używamy tuple do przechwytywania wielu WYJĄTKÓW w jednym bloku except.

try:
    do_the_thing()
except (TypeError, KeyError, IndexError) as e:
    do_the_other_thing()
 0
Author: Raksha Saini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-02 05:32:20