e.printStackTrace-Äquivalent in Python

207

Ich weiß, dass print(e)(wobei e eine Ausnahme ist) die aufgetretene Ausnahme druckt, aber ich habe versucht, das Python-Äquivalent von Java zu finden, das e.printStackTrace()die Ausnahme genau auf die aufgetretene Zeile zurückführt und die gesamte Ablaufverfolgung druckt.

Könnte mir bitte jemand das Äquivalent von e.printStackTrace()in Python sagen ?

koool
quelle

Antworten:

280
import traceback
traceback.print_exc()

Wenn Sie dies innerhalb eines except ...:Blocks tun , wird automatisch die aktuelle Ausnahme verwendet. Weitere Informationen finden Sie unter http://docs.python.org/library/traceback.html .

DiebMaster
quelle
10
Wenn Sie in einem Container wie Jython arbeiten und daher nicht nur die Ablaufverfolgung drucken können, können Sie format_excstattdessen eine Zeichenfolge abrufen.
Selten needy
116

Es gibt auch logging.exception.

import logging

...

try:
    g()
except Exception as ex:
    logging.exception("Something awful happened!")
    # will print this message followed by traceback

Ausgabe:

ERROR 2007-09-18 23:30:19,913 error 1294 Something awful happened!
Traceback (most recent call last):
  File "b.py", line 22, in f
    g()
  File "b.py", line 14, in g
    1/0
ZeroDivisionError: integer division or modulo by zero

(Von http://blog.tplus1.com/index.php/2007/09/28/the-python-logging-module-is-much-better-than-print-statements/ über So drucken Sie den vollständigen Traceback ohne Programm anhalten? )

david.libremone
quelle
Was sind die Vor- / Nachteile davon gegenüber traceback.print_exc()?
Nathan
18

e.printStackTrace-Äquivalent in Python

In Java führt dies Folgendes aus ( Dokumente ):

public void printStackTrace()

Druckt dieses Wurfobjekt und seine Rückverfolgung zum Standardfehlerstrom ...

Dies wird folgendermaßen verwendet:

try
{ 
// code that may raise an error
}
catch (IOException e)
{
// exception handling
e.printStackTrace();
}

In Java ist der Standardfehlerstrom ungepuffert, sodass die Ausgabe sofort eintrifft.

Die gleiche Semantik in Python 2 ist:

import traceback
import sys
try: # code that may raise an error
    pass 
except IOError as e: # exception handling
    # in Python 2, stderr is also unbuffered
    print >> sys.stderr, traceback.format_exc()
    # in Python 2, you can also from __future__ import print_function
    print(traceback.format_exc(), file=sys.stderr)
    # or as the top answer here demonstrates, use:
    traceback.print_exc()
    # which also uses stderr.

Python 3

In Python 3 können wir den Traceback direkt vom Ausnahmeobjekt abrufen (was sich für Thread-Code wahrscheinlich besser verhält). Außerdem ist stderr zeilengepuffert , aber die Druckfunktion erhält ein Flush-Argument, sodass dieses sofort an stderr gedruckt wird:

    print(traceback.format_exception(None, # <- type(e) by docs, but ignored 
                                     e, e.__traceback__),
          file=sys.stderr, flush=True)

Fazit:

In Python 3 wird daher die Ausgabe gepufferttraceback.print_exc() , obwohl sie sys.stderr standardmäßig verwendet wird , und Sie können sie möglicherweise verlieren. Um in Python 3 eine möglichst gleichwertige Semantik zu erhalten, verwenden Sie printmit flush=True.

Aaron Hall
quelle
3

Zusätzlich zu den anderen großen Antworten, können wir die Python verwenden loggingBibliothek debug(), info(), warning(), error(), und critical()Methoden. Zitieren aus den Dokumenten für Python 3.7.4 ,

Es gibt drei Schlüsselwortargumente in kwargs, die überprüft werden: exc_info, das, wenn es nicht als falsch ausgewertet wird, dazu führt, dass der Protokollierungsnachricht Ausnahmeinformationen hinzugefügt werden.

Dies bedeutet, dass Sie die Python- loggingBibliothek zum Ausgeben einer debug()oder eines anderen Nachrichtentyps verwenden können und die loggingBibliothek den Stack-Trace in ihre Ausgabe einbezieht. In diesem Sinne können wir Folgendes tun:

import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

def f():
    a = { 'foo': None }
    # the following line will raise KeyError
    b = a['bar']

def g():
    f()

try:
    g()
except Exception as e:
    logger.error(str(e), exc_info=True)

Und es wird ausgegeben:

'bar'
Traceback (most recent call last):
  File "<ipython-input-2-8ae09e08766b>", line 18, in <module>
    g()
  File "<ipython-input-2-8ae09e08766b>", line 14, in g
    f()
  File "<ipython-input-2-8ae09e08766b>", line 10, in f
    b = a['bar']
KeyError: 'bar'
MikeyE
quelle