Ich sehe das in keiner der anderen Antworten erwähnt. Wenn Sie aus irgendeinem Grund ein Exception-Objekt weitergeben...
In Python 3.5+ können Sie einen Trace von einem Exception-Objekt erhalten, indem Sie traceback.TracebackException.from_exception() . Zum Beispiel:
import traceback
def stack_lvl_3():
raise Exception('a1', 'b2', 'c3')
def stack_lvl_2():
try:
stack_lvl_3()
except Exception as e:
# raise
return e
def stack_lvl_1():
e = stack_lvl_2()
return e
e = stack_lvl_1()
tb1 = traceback.TracebackException.from_exception(e)
print(''.join(tb1.format()))
Der obige Code führt jedoch zu:
Traceback (most recent call last):
File "exc.py", line 10, in stack_lvl_2
stack_lvl_3()
File "exc.py", line 5, in stack_lvl_3
raise Exception('a1', 'b2', 'c3')
Exception: ('a1', 'b2', 'c3')
Dies sind nur zwei Ebenen des Stapels, im Gegensatz zu dem, was auf dem Bildschirm ausgegeben worden wäre, wenn die Ausnahme in stack_lvl_2()
und nicht abgefangen werden (entfernen Sie das Kommentarzeichen # raise
Zeile).
So wie ich es verstehe, liegt das daran, dass eine Ausnahme nur den aktuellen Stand des Stacks aufzeichnet, wenn sie ausgelöst wird, stack_lvl_3()
in diesem Fall. Bei der Weitergabe durch den Stapel werden weitere Ebenen zu seinem __traceback__
. Aber wir haben es abgefangen in stack_lvl_2()
Das heißt, es konnten nur die Stufen 3 und 2 aufgezeichnet werden. Um die vollständige Aufzeichnung auf stdout zu erhalten, müssten wir sie auf der höchsten (niedrigsten?) Stufe abfangen:
import traceback
def stack_lvl_3():
raise Exception('a1', 'b2', 'c3')
def stack_lvl_2():
stack_lvl_3()
def stack_lvl_1():
stack_lvl_2()
try:
stack_lvl_1()
except Exception as exc:
tb = traceback.TracebackException.from_exception(exc)
print('Handled at stack lvl 0')
print(''.join(tb.stack.format()))
Daraus ergibt sich:
Handled at stack lvl 0
File "exc.py", line 17, in <module>
stack_lvl_1()
File "exc.py", line 13, in stack_lvl_1
stack_lvl_2()
File "exc.py", line 9, in stack_lvl_2
stack_lvl_3()
File "exc.py", line 5, in stack_lvl_3
raise Exception('a1', 'b2', 'c3')
Beachten Sie, dass der Stapeldruck anders ist, die erste und die letzte Zeile fehlen. Da es sich um eine diferente format()
.
Das Abfangen der Ausnahme so weit wie möglich von dem Punkt entfernt, an dem sie ausgelöst wurde, sorgt für einfacheren Code und liefert gleichzeitig mehr Informationen.
17 Stimmen
Das ist zwar keine vollständige Antwort, aber vielleicht möchte jemand wissen, dass man viele Informationen erhalten kann, wenn man in
err.__traceback__
(zumindest in Python 3.x)35 Stimmen
Es wurde 825.000 Mal aufgerufen, während man versuchte, herauszufinden, wie man seine Stacktraces ausdrucken kann. Das ist ein weiteres Zen von Python.
13 Stimmen
Anscheinend bin ich der Einzige auf der Welt, der den Stapel ausdrucken möchte. wenn kein Fehler vorliegt (= nur um zu sehen, wie ich genau zu dieser Zeile gekommen bin (es ist nicht mein Code, und er ist so hässlich, dass ich nicht weiß, wie er hierher gekommen ist!)).
1 Stimmen
Alle Antworten auf diese Frage sind der ultimative Anfängerleitfaden zum Debuggen von Python-Code