e.printStackTrace equivalente en python

208

Sé que print(e)(donde e es una excepción) imprime la excepción ocurrida, pero estaba tratando de encontrar el equivalente en Python de Java e.printStackTrace()que rastrea exactamente la excepción a qué línea ocurrió e imprime todo el rastro.

¿Alguien podría decirme el equivalente de e.printStackTrace()en Python?

koool
fuente

Respuestas:

281
import traceback
traceback.print_exc()

Al hacer esto dentro de un except ...:bloque, usará automáticamente la excepción actual. Consulte http://docs.python.org/library/traceback.html para obtener más información.

ThiefMaster
fuente
10
Si está trabajando dentro de algún tipo de contenedor como Jython y, por lo tanto, no puede simplemente imprimir la traza, puede format_excobtener una cadena.
SeldomNeedy
116

También existe logging.exception.

import logging

...

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

Salida:

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

(De http://blog.tplus1.com/index.php/2007/09/28/the-python-logging-module-is-much-better-than-print-statements/ a través de Cómo imprimir el rastreo completo sin detener el programa? )

david.libremone
fuente
¿Cuáles son las ventajas / desventajas de este versus traceback.print_exc()?
Nathan
18

e.printStackTrace equivalente en python

En Java, esto hace lo siguiente ( docs ):

public void printStackTrace()

Imprime este elemento arrojable y su retroceso a la secuencia de error estándar ...

Esto se usa así:

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

En Java, la secuencia de error estándar no tiene búfer para que la salida llegue de inmediato.

La misma semántica en Python 2 son:

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, podemos obtener el rastreo directamente del objeto de excepción (que probablemente se comporta mejor para el código enhebrado). Además, stderr tiene un buffer de línea , pero la función de impresión obtiene un argumento de vaciado, por lo que esto se imprimirá inmediatamente en stderr:

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

Conclusión:

En Python 3, por lo tanto, traceback.print_exc()aunque usa sys.stderr de forma predeterminada , amortiguaría la salida y posiblemente la pierda. Entonces, para obtener la semántica más equivalente posible, en Python 3, use printcon flush=True.

Aaron Hall
fuente
3

Agregando a los otros grandes respuestas, podemos usar el pitón loggingde la biblioteca debug(), info(), warning(), error(), y critical()métodos. Citando de los documentos para Python 3.7.4 ,

Hay tres argumentos de palabras clave en kwargs que se inspeccionan: exc_info que, si no se evalúa como falso, hace que se agregue información de excepción al mensaje de registro.

Lo que esto significa es que puede usar la loggingbiblioteca de Python para generar un debug()mensaje u otro tipo de mensaje, y la loggingbiblioteca incluirá el seguimiento de la pila en su salida. Con esto en mente, podemos hacer lo siguiente:

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)

Y dará salida:

'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
fuente