Der Unterschied besteht darin, dass wenn Sie from
verwenden, das __cause__
Attribut gesetzt wird und die Meldung besagt, dass die Ausnahme direkt durch verursacht wurde. Wenn Sie das from
auslassen, wird kein __cause__
festgelegt, aber das __context__
Attribut kann ebenfalls festgelegt sein und der Traceback zeigt dann den Kontext als bei der Bearbeitung eines anderen Fehlers ist etwas passiert.
Das Setzen des __context__
passiert, wenn Sie raise
in einem Ausnahmehandler verwendet haben; wenn Sie raise
an anderer Stelle verwenden, wird auch kein __context__
festgelegt.
Wenn ein __cause__
festgelegt ist, wird auch ein __suppress_context__ = True
Flag auf der Ausnahme festgelegt; wenn __suppress_context__
auf True
gesetzt ist, wird der __context__
ignoriert, wenn ein Traceback gedruckt wird.
Beim Werfen aus einem Ausnahmebehandler heraus, in dem Sie den Kontext nicht anzeigen möchten (keine bei der Bearbeitung einer anderen Ausnahme passierte Meldung), verwenden Sie raise ... from None
, um __suppress_context__
auf True
zu setzen.
Mit anderen Worten, Python setzt einen Kontext bei Ausnahmen, damit Sie nachvollziehen können, wo eine Ausnahme ausgelöst wurde, und können sehen, ob eine andere Ausnahme durch sie ersetzt wurde. Sie können auch eine Ursache zu einer Ausnahme hinzufügen, um den Traceback explizit über die andere Ausnahme zu informieren (verwenden Sie andere Wörter), und der Kontext wird ignoriert (kann jedoch beim Debuggen weiterhin untersucht werden). Mit raise ... from None
können Sie verhindern, dass der Kontext gedruckt wird.
Siehe die raise
Anweisungsdokumentation:
Die from
Klausel wird für die Verkettung von Ausnahmen verwendet: Wenn sie angegeben wird, muss der zweite Ausdruck eine andere Ausnahmeklasse oder Instanz sein, die dann der ausgelösten Ausnahme als das __cause__
Attribut (das beschreibbar ist) angehängt wird. Wenn die ausgelöste Ausnahme nicht behandelt wird, werden beide Ausnahmen gedruckt:
>>> try:
... print(1 / 0)
... except Exception as exc:
... raise RuntimeError("Etwas Schlechtes ist passiert") from exc
...
Traceback (most recent call last):
File "", line 2, in
ZeroDivisionError: int division or modulo by zero
Die obige Ausnahme war die direkte Ursache der folgenden Ausnahme:
Traceback (most recent call last):
File "", line 4, in
RuntimeError: Etwas Schlechtes ist passiert
Ein ähnlicher Mechanismus funktioniert implizit, wenn eine Ausnahme innerhalb eines Ausnahmehandlers oder einer finally
-Klausel ausgelöst wird: die vorherige Ausnahme wird dann als das __context__
Attribut der neuen Ausnahme angehängt:
>>> try:
... print(1 / 0)
... except:
... raise RuntimeError("Etwas Schlechtes ist passiert")
...
Traceback (most recent call last):
File "", line 2, in
ZeroDivisionError: int division or modulo by zero
Bei der Behandlung der obigen Ausnahme ist eine weitere Ausnahme aufgetreten:
Traceback (most recent call last):
File "", line 4, in
RuntimeError: Etwas Schlechtes ist passiert
Siehe auch die Dokumentation zu den integrierten Ausnahmen für Details zu den am Ausnahmen angehängten Kontext- und Ursacheninformationen.