Équivalent e.printStackTrace en python

208

Je sais que print(e)(où e est une exception) imprime l'exception survenue, mais j'essayais de trouver l'équivalent python de Java e.printStackTrace()qui trace exactement l'exception jusqu'à quelle ligne elle s'est produite et imprime la trace entière de celle-ci.

Quelqu'un pourrait-il me dire l'équivalent de e.printStackTrace()Python?

Koool
la source

Réponses:

281
import traceback
traceback.print_exc()

Lorsque vous faites cela à l'intérieur d'un except ...:bloc, il utilise automatiquement l'exception actuelle. Voir http://docs.python.org/library/traceback.html pour plus d'informations.

ThiefMaster
la source
10
Si vous travaillez à l'intérieur d'une sorte de conteneur tel que Jython et ne pouvez donc pas simplement imprimer la trace, vous pouvez à la format_excplace obtenir une chaîne.
SeldomNeedy
116

Il y en a aussi logging.exception.

import logging

...

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

Production:

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

(Sur http://blog.tplus1.com/index.php/2007/09/28/the-python-logging-module-is-much-better-than-print-statements/ via Comment imprimer le traçage complet sans interrompre le programme? )

david.libremone
la source
Quels sont les avantages / inconvénients de cela par rapport à traceback.print_exc()?
Nathan
19

Équivalent e.printStackTrace en python

En Java, cela fait les choses suivantes ( docs ):

public void printStackTrace()

Imprime ce jetable et sa trace dans le flux d'erreur standard ...

Ceci est utilisé comme ceci:

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

En Java, le flux d'erreur standard n'est pas mis en mémoire tampon de sorte que la sortie arrive immédiatement.

La même sémantique en Python 2 est:

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

En Python 3, nous pouvons obtenir le traceback directement à partir de l'objet exception (qui se comporte probablement mieux pour le code threadé). De plus, stderr est mis en mémoire tampon , mais la fonction print obtient un argument flush, donc ce serait immédiatement imprimé sur stderr:

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

Conclusion:

En Python 3, par conséquent, traceback.print_exc()bien qu'il utilise sys.stderr par défaut , il tamponnerait la sortie, et vous pourriez éventuellement la perdre. Donc, pour obtenir la sémantique la plus équivalente possible, en Python 3, utilisez printavec flush=True.

Aaron Hall
la source
3

Ajout aux autres grandes réponses, nous pouvons utiliser le Python loggingde la bibliothèque debug(), info(), warning(), error()et critical()méthodes. Citant des documents pour Python 3.7.4 ,

Il y a trois arguments de mots clés dans kwargs qui sont inspectés: exc_info qui, s'il n'est pas évalué comme faux, entraîne l'ajout d'informations d'exception au message de journalisation.

Cela signifie que vous pouvez utiliser la loggingbibliothèque Python pour générer un debug()ou un autre type de message, et la loggingbibliothèque inclura la trace de pile dans sa sortie. Dans cette optique, nous pouvons procéder comme suit:

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)

Et il produira:

'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
la source