Pytanie Złap kilka wyjątków w jednym wierszu (z wyjątkiem bloku)


Wiem, że mogę:

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 w dwóch różnych wyjątkach, najlepsze, co mogę teraz zrobić, to zrobić:

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

Czy jest jakiś sposób, że mogę zrobić coś takiego (ponieważ akcja do obu wyjątków jest 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

Tak więc mój wysiłek, by złapać dwa odrębne wyjątki, nie jest dokładnie taki.

Czy jest jakiś sposób na zrobienie tego?


1963
2018-06-24 15:55


pochodzenie




Odpowiedzi:


Od Dokumentacja Pythona:

Klauzula except może na przykład wskazywać wiele wyjątków jako nawiasową krotkę

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Lub tylko dla Pythona 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

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


2712
2018-06-24 15:56



Czy jest możliwe zapisanie żądanych wyjątków w iteracji, a następnie przechwycenie iteracji? Próbuję zmienić listę ostrzeżeń w błędy za pomocą warnings.filterwarningsi nie chcę dwukrotnie określać listy ostrzeżeń. - BallpointBen
Spróbowałem ... z a list, i to spowodowało TypeError. Wygląda na to, że błędy muszą być w tuple za złapanie do pracy zgodnie z oczekiwaniami. - BallpointBen
Dlaczego kiedykolwiek używałeś listy, gdy wyraźnie zobaczysz, że udokumentowano, że w tym przypadku potrzebna jest krotka? - bernie
Nie było jasne, czy "krotochwila" była jedynie syntaktyczna, czy też wymagana była bona fide krotka. "Parentedized" wprowadza w błąd, ponieważ możesz utworzyć krotkę bez nawiasów w innym miejscu, a następnie użyć jej w exceptlinia. To jest tylko koniecznie parenthesized, jeśli utworzone w except linia. - BallpointBen


Jak przechwycić wiele wyjątków w jednym wierszu (z wyjątkiem bloku)

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. The as słowo kluczowe jest używane do przypisania. Możesz użyć dowolnej nazwy obiektu błędu, wolę error osobiście.

Najlepsze praktyki

Aby to zrobić w sposób zgodny z Pythonem, musisz oddzielić Wyjątki przecinkami i zawijać je nawiasami, aby odróżnić od wcześniejszej składni przypisanej instancji wyjątku do nazwy zmiennej, podążając za typem wyjątku, aby zostać złapanym za pomocą przecinek.

Oto przykład prostego użycia:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    quit(0)

Podaję tylko te wyjątki, aby uniknąć ukrywania błędów, które w razie napotkania oczekuję od śledzenia całego stosu.

Zostało to udokumentowane tutaj: https://docs.python.org/tutorial/errors.html

Możesz przypisać wyjątek do zmiennej, (e jest powszechne, ale możesz preferować bardziej szczegółową zmienną, jeśli masz długą obsługę wyjątku lub twój IDE podświetla tylko selekcje większe niż ta, tak jak moja.) Instancja ma atrybut args. Oto przykład:

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

Zauważ, że w Pythonie 3, err obiekt jest poza zakresem, gdy except blok jest zakończony.

Przestarzałe

Możesz zobaczyć kod, który przypisuje błąd przecinkiem. To użycie, jedyna forma dostępna w Pythonie 2.5 i wcześniejszych, jest przestarzała, a jeśli chcesz, aby twój kod był kompatybilny w przód w Pythonie 3, powinieneś zaktualizować składnię, aby użyć nowego formularza:

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

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

The suppress Menedżer kontekstu

Przyjęta odpowiedź to naprawdę 4 linie kodu, minimum:

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

The try, except, pass linie mogą być obsługiwane w jednej linii z pomiń menedżer kontekstów, dostępny w Pythonie 3.4:

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

Więc kiedy chcesz pass z pewnymi wyjątkami użyj suppress.


186
2018-06-21 04:20



Najbardziej kompletna odpowiedź. Jedyny, który określa sposób korzystania z except (KeyboardInterrupt, EOFError): składnia. - Eduard Luca


W przypadku Pythona w wersji 2.5 i wcześniejszych poprawna składnia to:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

Gdzie e jest instancją wyjątku.


49
2018-05-13 12:37



Nie powinieneś przypisywać e przecinkiem, jeśli chcesz mieć kompatybilny kod do przodu, a Python 2.5 nie jest już aktualizowany: mail.python.org/pipermail/python-committers/2011- October /... - Aaron Hall♦
tak, ale z pythonem 2.5 nie ma innego sposobu. Rozwiązanie wyraźnie określa (starą) wersję. - Jean-François Fabre


Od Dokumentacja Pythona -> 8.3 Obsługa wyjątków:

ZA try oświadczenie może zawierać więcej niż jedną klauzulę, którą należy podać   procedury obsługi dla różnych wyjątków. Może być najwyżej jeden program obsługi   wykonany. Obsługi obsługują tylko wyjątki, które występują w   Odpowiednia klauzula try, a nie w innych procedurach tej samej próby   komunikat. Klauzula except może nazywać wiele wyjątków jako   krotka z nawiasami, na przykład:

except (RuntimeError, TypeError, NameError):
    pass

Zwróć uwagę, że nawiasy wokół tej krotki są wymagane, ponieważ   z wyjątkiem ValueError, e: była składnia używana do tego, co normalnie   napisany jako except ValueError as e: w nowoczesnym Pythonie (opisany   poniżej). Stara składnia jest nadal obsługiwana ze względu na kompatybilność wsteczną.   To znaczy except RuntimeError, TypeError nie jest równoważne    except (RuntimeError, TypeError): ale except RuntimeError as TypeError: co nie jest tym, czego chcesz.


37
2017-10-30 10:01





Jeśli często używasz dużej liczby wyjątków, możesz wstępnie zdefiniować krotkę, więc nie musisz jej wielokrotnie wpisywać.

#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 ty również musisz łapać inne wyjątki niż te w predefiniowana krotka, musisz zdefiniować inny blok z wyjątkiem.

  2. Jeśli nie możesz tolerować zmiennej globalnej, zdefiniuj ją w main () i przekazać go tam, gdzie jest to potrzebne ...


15
2017-09-18 01:36





Jednym ze sposobów, aby to zrobić 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 zablokuj i wywołaj to przez wszystkie 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 drugi nie jest najlepszym sposobem na zrobienie tego, ale pokazuję tylko kilka sposobów na zrobienie tego.


5
2017-08-17 11:56





Dokumentacja Python 2.7 stwierdza, że:

Oświadczenie try może zawierać więcej niż jedną klauzulę except   procedury obsługi dla różnych wyjątków. Może być najwyżej jeden program obsługi   wykonany. Obsługi obsługują tylko wyjątki, które występują w   Odpowiednia klauzula try, a nie w innych procedurach tej samej próby   komunikat. Klauzula except może nazywać wiele wyjątków jako   krotka z nawiasami, na przykład:

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

Uwaga   że nawiasy okrągłe wokół tej krotki są wymagane, ponieważ z wyjątkiem   ValueError, e: była składnią używaną do tego, co zwykle jest napisane jako   z wyjątkiem ValueError jako e: we współczesnym Pythonie (opisanym poniżej). Stary   Składnia jest nadal obsługiwana w celu zapewnienia kompatybilności wstecznej. To znaczy   z wyjątkiem RuntimeError, TypeError nie jest równoważny z wyjątkiem   (RuntimeError, TypeError): ale z wyjątkiem RuntimeError jako TypeError:   co nie jest tym, czego chcesz.


3
2017-12-05 14:05