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 na True
, 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__
na True
.
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 :
from
Punkt stosuje się wyjątek łańcuchowych: jeśli podano, drugie wyrażenie może być inna klasa wyjątkiem lub wystąpienie, co zostanie dołączony do uniesionego wyjątkiem jako __cause__
atrybut, (który jest zapisywalny). Jeśli zgłoszony wyjątek nie zostanie obsłużony, zostaną wydrukowane oba wyjątki:
>>> try:
... print(1 / 0)
... except Exception as exc:
... raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened
Podobny mechanizm działa domyślnie, jeśli wyjątek zostanie zgłoszony w procedurze obsługi wyjątku lub w finally
klauzuli: poprzedni wyjątek jest następnie dołączany jako __context__
atrybut nowego wyjątku :
>>> try:
... print(1 / 0)
... except:
... raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened
Zobacz także dokumentację Wbudowane wyjątki, aby uzyskać szczegółowe informacje na temat kontekstu i informacje o przyczynie związane z wyjątkami.