Jaka jest różnica między raise
i raise from
w Pythonie?
try:
raise ValueError
except Exception as e:
raise IndexError
co daje
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError
IndexError
i
try:
raise ValueError
except Exception as e:
raise IndexError from e
co daje
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError from e
IndexError
python
python-3.x
syntax
exception-handling
Darkfeline
źródło
źródło
raise IndexError from None
, powiedzmy.raise IndexError from False
podnosi aTypeError
nie anIndexError
. Zrobił mi dzień.Odpowiedzi:
Różnica polega na tym, że gdy używasz
from
,__cause__
atrybut jest ustawiony, a komunikat stwierdza, że wyjątek był bezpośrednio spowodowany . Jeśli pominiesz,from
to nie__cause__
jest ustawione, ale__context__
atrybut może być również ustawiony, a traceback pokazuje kontekst, jak podczas obsługi czegoś innego .Ustawienie
__context__
dzieje się, jeśli użyłeśraise
w module obsługi wyjątków; jeśli używałeśraise
nigdzie indziej, nie__context__
jest ustawione.Jeśli
__cause__
ustawiony jest a,__suppress_context__ = True
flaga jest również ustawiana na wyjątku; gdy__suppress_context__
jest ustawiony naTrue
, to__context__
jest ignorowane podczas drukowania śledzenia.W przypadku zgłaszania zdarzenia z procedury obsługi wyjątków, w której nie chcesz pokazywać kontekstu (nie chcesz, aby podczas obsługi pojawił się inny komunikat o zdarzeniu wyjątku ), użyj przycisku,
raise ... from None
aby ustawić__suppress_context__
naTrue
.Innymi słowy, Python określa kontekst wyjątków, dzięki czemu można introspekcji, gdzie został zgłoszony wyjątek, pozwalając zobaczyć, czy inny wyjątek został przez niego zastąpiony. Możesz także dodać przyczynę do wyjątku, dzięki czemu funkcja śledzenia wyraźnie mówi o innym wyjątku (użyj innego sformułowania), a kontekst jest ignorowany (ale nadal może być introspekcyjny podczas debugowania). Użycie
raise ... from None
pozwala pominąć drukowany kontekst.Zobacz dokumentację
raise
oświadczenia :Zobacz także dokumentację Wbudowane wyjątki, aby uzyskać szczegółowe informacje na temat kontekstu i informacje o przyczynie związane z wyjątkami.
źródło
from
i__cause__
zamiast domniemanych__context__
? Czy istnieją przypadki, w których można załączyć inny wyjątek niż ten złapany przezexcept
?DatabaseError
jeśli otwarcie bazy danych nie powiedzie się. Ale jeśli awaria jest spowodowanaIOError
niepowodzeniem otwierania pliku lubHTTPError
niedziałaniem adresu URL, to jest to kontekst, który chcesz jawnie uwzględnić, więc programista korzystający z interfejsu API może debugować, dlaczego tak jest. W tym momencie używaszraise DatabaseError from original_exception
.IOError
lubHTTPError
na ich konsumentów, wtedy musieliby użytkuraise NewException from databaseexception.__cause__
, teraz za pomocą innego wyjątku odDatabaseException
że po prostu złapać.foo
i chcesz zgłosić nowy wyjątekbar
? Następnie możesz użyćraise bar from foo
i ustawić stan Python, któryfoo
bezpośrednio spowodowałbar
. Jeśli nie używaćfrom foo
, a następnie Python będzie nadal drukować zarówno, ale stwierdzają, że podczas przenoszeniafoo
,bar
został podniesiony , inny komunikat, przeznaczony do flaga możliwy błąd w obsłudze błędów.