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, fromto 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ś raisew module obsługi wyjątków; jeśli używałeś raisenigdzie indziej, nie __context__jest ustawione.
Jeśli __cause__ustawiony jest a, __suppress_context__ = Trueflaga 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 Noneaby 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 Nonepozwala pominąć drukowany kontekst.
Zobacz dokumentację raiseoświadczenia :
fromPunkt 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 finallyklauzuli: 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.