python - plotting - Trace-Back-Informationen aus einem Ausnahmeobjekt extrahieren




python plotting libraries (3)

Die Antwort auf diese Frage hängt von der Version von Python ab, die Sie verwenden.

In Python 3

__traceback__ einfach: Ausnahmen sind mit einem __traceback__ Attribut ausgestattet, das das __traceback__ enthält. Dieses Attribut ist auch beschreibbar und kann bequem mit der Methode with_traceback von Ausnahmen festgelegt werden:

raise Exception("foo occurred").with_traceback(tracebackobj)

Diese Funktionen werden minimal als Teil der raise Dokumentation beschrieben.

Der ganze Kredit für diesen Teil der Antwort sollte an Vyctor gehen, der diese Information zuerst gepostet hat . Ich füge es hier nur ein, weil diese Antwort an der Spitze stecken bleibt und Python 3 immer häufiger wird.

In Python 2

Es ist ärgerlich komplex. Das Problem mit Tracebacks ist, dass sie Verweise auf Stack-Frames haben und Stack-Frames Verweise auf die Trace-Backs haben, die Verweise auf Stack-Frames haben , die Verweise auf ... haben. Sie erhalten die Idee. Dies verursacht Probleme für den Garbage Collector. (Danke an ecatmur für den ersten Hinweis darauf.)

Der beste Weg, dies zu lösen, wäre, den Zyklus nach dem Verlassen der except Klausel zu unterbrechen, was Python 3 tut. Die Python 2-Lösung ist viel hässlicher: Sie erhalten eine Ad-hoc-Funktion, sys.exc_info() , die nur innerhalb der sys.exc_info() Klausel funktioniert . Sie gibt ein Tupel zurück, das die Ausnahme, den Ausnahmetyp und das Traceback für die gerade behandelte Ausnahme enthält.

Wenn Sie also innerhalb der sys.exec_info() Klausel sind, können Sie die Ausgabe von sys.exec_info() zusammen mit dem traceback Modul verwenden, um verschiedene nützliche Dinge zu tun:

>>> import sys, traceback
>>> def raise_exception():
...     try:
...         raise Exception
...     except Exception:
...         ex_type, ex, tb = sys.exc_info()
...         traceback.print_tb(tb)
...     finally:
...         del tb
... 
>>> raise_exception()
  File "<stdin>", line 3, in raise_exception

Aber wie Ihre Editierung anzeigt, versuchen Sie, das Traceback zu erhalten, das gedruckt worden wäre, wenn Ihre Exception nicht behandelt worden wäre, nachdem sie bereits behandelt wurde. Das ist eine viel schwierigere Frage. Leider gibt sys.exc_info (None, None, None) wenn keine Ausnahme behandelt wird. Andere verwandte sys Attribute helfen ebenfalls nicht. sys.exc_traceback ist veraltet und nicht definiert, wenn keine Ausnahme behandelt wird. sys.last_traceback scheint perfekt zu sein, aber es scheint nur während interaktiver Sitzungen definiert zu sein.

Wenn Sie steuern können, wie die Ausnahme ausgelöst wird, können Sie möglicherweise inspect und eine benutzerdefinierte Ausnahme zum Speichern einiger Informationen verwenden. Aber ich bin mir nicht ganz sicher, wie das funktionieren würde.

Um die Wahrheit zu sagen, ist es eine ungewöhnliche Sache, eine Ausnahme zu fangen und zurückzugeben. Dies könnte ein Zeichen dafür sein, dass Sie sowieso umgestalten müssen.

https://code.i-harness.com

Gibt es ein Exception-Objekt (unbekannter Herkunft) gibt es Möglichkeit, seine Rückverfolgung zu erhalten? Ich habe Code wie folgt:

def stuff():
   try:
       .....
       return useful
   except Exception as e:
       return e

result = stuff()
if isinstance(result, Exception):
    result.traceback <-- How?

Wie kann ich das Traceback aus dem Exception-Objekt extrahieren, sobald ich es habe?


Eine Möglichkeit, die Rückverfolgung als String von einem Ausnahmeobjekt in Python 3 zu erhalten:

import traceback

# `e` is an exception object that you get from somewhere
traceback_str = ''.join(traceback.format_tb(e.__traceback__))

traceback.format_tb(...) gibt eine Liste von Strings zurück. ''.join(...) verbindet sie miteinander. Weitere Informationen finden Sie unter https://docs.python.org/3/library/traceback.html#traceback.format_exc


Seit Python 3.0 [PEP 3109] hat die eingebaute Exception ein Attribut __traceback__ , das ein traceback object enthält (mit Python 3.2.3):

>>> try:
...     raise Exception()
... except Exception as e:
...     tb = e.__traceback__
...
>>> tb
<traceback object at 0x00000000022A9208>

Das Problem ist, dass ich nach dem Googlen von __traceback__ für eine Weile nur wenige Artikel gefunden habe, aber keiner von ihnen beschreibt, ob und warum Sie __traceback__ sollten (nicht).

Die Python 3-Dokumentation für raise besagt jedoch:

Ein Traceback-Objekt wird normalerweise automatisch erstellt, wenn eine Ausnahme __traceback__ und als __traceback__ Attribut, das beschreibbar ist, angehängt wird.

Also nehme ich an, es soll benutzt werden.





exception-handling