Ich möchte den Namen des Fehlers und die Traceback-Details in einer Variablen speichern. Hier ist mein Versuch.
import sys
try:
try:
print x
except Exception, ex:
raise NameError
except Exception, er:
print "0", sys.exc_info()[0]
print "1", sys.exc_info()[1]
print "2", sys.exc_info()[2]
Ausgabe:
0 <type 'exceptions.NameError'>
1
2 <traceback object at 0xbd5fc8>
Gewünschte Ausgabe:
0 NameError
1
2 Traceback (most recent call last):
File "exception.py", line 6, in <module>
raise NameError
PS Ich weiß, dass dies mit dem Traceback-Modul einfach möglich ist, aber ich möchte die Verwendung des Objekts sys.exc_info () [2] hier kennen.
python
exception-handling
codersofthedark
quelle
quelle
<python install path>/Lib/traceback.py
) für weitere Informationen.Antworten:
So mache ich es:
Sie sollten sich jedoch die Traceback-Dokumentation ansehen , da Sie dort möglicherweise geeignetere Methoden finden, je nachdem, wie Sie Ihre Variable anschließend verarbeiten möchten ...
quelle
sys.exc_info()[2].tb_frame.f_code.co_names[3]
, aber es macht überhaupt keinen Sinn ... Wenn es ein Modul gibt, dastraceback
in der Standardbibliothek aufgerufen wird , gibt es einen Grund dafür ... :)traceback.format_exception(*sys.exc_info())
ist der Weg, es zu tun. Aber das ist funktional gleichbedeutend mittraceback.format_exc()
.sys.exc_info () gibt ein Tupel mit drei Werten zurück (Typ, Wert, Rückverfolgung).
Zum Beispiel im folgenden Programm
Wenn wir nun das Tupel drucken, sind dies die Werte.
Die obigen Details können auch durch einfaches Drucken der Ausnahme im Zeichenfolgenformat abgerufen werden.
quelle
Verwenden
traceback.extract_stack()
Sie diese Option, wenn Sie bequem auf Modul- und Funktionsnamen sowie Zeilennummern zugreifen möchten.Verwenden
''.join(traceback.format_stack())
Sie diese Option, wenn Sie nur eine Zeichenfolge möchten, die dertraceback.print_stack()
Ausgabe ähnelt.Beachten Sie, dass auch bei
''.join()
Ihnen eine mehrzeilige Zeichenfolge angezeigt wird, da die Elemente vonformat_stack()
enthalten sind\n
. Siehe Ausgabe unten.Denken Sie daran
import traceback
.Hier ist die Ausgabe von
traceback.extract_stack()
. Formatierung zur besseren Lesbarkeit hinzugefügt.Hier ist die Ausgabe von
''.join(traceback.format_stack())
. Formatierung zur besseren Lesbarkeit hinzugefügt.quelle
Seien Sie vorsichtig, wenn Sie das Ausnahmeobjekt oder das Traceback-Objekt aus dem Ausnahmebehandler entfernen, da dies zu Zirkelverweisen führt und
gc.collect()
nicht erfasst werden kann. Dies scheint ein besonderes Problem in der ipython / jupyter-Notebook-Umgebung zu sein, in der das Traceback-Objekt nicht zum richtigen Zeitpunkt gelöscht wird und sogar explizit aufgerufen wirdgc.collect()
infinally
section nichts bewirkt. Und das ist ein großes Problem, wenn Sie einige große Objekte haben, deren Speicher aus diesem Grund nicht zurückgefordert wird (z. B. CUDA-Ausnahmen für nicht genügend Speicher, für die ohne diese Lösung ein vollständiger Kernel-Neustart erforderlich ist).Wenn Sie das Traceback-Objekt speichern möchten, müssen Sie es im Allgemeinen aus Verweisen auf Folgendes löschen
locals()
:Im Falle eines Jupyter-Notebooks müssen Sie dies zumindest im Ausnahmebehandler tun:
Getestet mit Python 3.7.
ps das problem mit ipython oder jupyter notebook env ist, dass es magie hat,
%tb
die den traceback speichert und ihn zu jedem späteren zeitpunkt verfügbar macht. Infolgedessen werdenlocals()
alle Frames, die am Traceback teilnehmen, erst freigegeben, wenn das Notebook beendet wird oder eine andere Ausnahme die zuvor gespeicherte Rückverfolgung überschreibt. Das ist sehr problematisch. Der Traceback sollte nicht ohne Reinigung der Frames gespeichert werden. Fix hier eingereicht .quelle
Das Objekt kann als Parameter in der
Exception.with_traceback()
Funktion verwendet werden:quelle