equivalente ao e.printStackTrace em python

208

Eu sei disso print(e) (onde e é uma exceção) imprime a exceção ocorrida, mas eu estava tentando encontrar o equivalente python do Java e.printStackTrace()que rastreia exatamente a exceção para qual linha ocorreu e imprime todo o rastreio dela.

Alguém poderia me dizer o equivalente e.printStackTrace()em Python?

koool
fonte

Respostas:

281
import traceback
traceback.print_exc()

Ao fazer isso dentro de um except ...:bloco, ele usará automaticamente a exceção atual. Veja http://docs.python.org/library/traceback.html para mais informações.

ThiefMaster
fonte
10
Se você estiver trabalhando dentro de algum tipo de contêiner como o Jython e, portanto, não puder apenas imprimir o rastreio, poderá format_excobter uma sequência.
SeldomNeedy 14/10
116

Há também logging.exception.

import logging

...

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

Resultado:

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

(Em http://blog.tplus1.com/index.php/2007/09/28/the-python-logging-module-is-much-better-than-print-statements/ via Como imprimir o rastreamento completo sem interromper o programa? )

david.libremone
fonte
Quais são as vantagens / desvantagens disso versus traceback.print_exc()?
Nathan
18

equivalente ao e.printStackTrace em python

Em Java, isso faz o seguinte ( docs ):

public void printStackTrace()

Imprime este lançamento e seu retorno ao fluxo de erros padrão ...

Isso é usado assim:

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

Em Java, o fluxo de erro padrão é sem buffer, para que a saída chegue imediatamente.

As mesmas semânticas no Python 2 são:

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

No Python 3, podemos obter o traceback diretamente do objeto de exceção (que provavelmente se comporta melhor para o código encadeado). Além disso, o stderr possui buffer de linha , mas a função print recebe um argumento de liberação, portanto isso seria imediatamente impresso no stderr:

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

Conclusão:

Portanto, no Python 3, traceback.print_exc()embora seja usado sys.stderr por padrão , o buffer será armazenado em buffer e você poderá perdê-lo. Portanto, para obter a semântica o mais equivalente possível, no Python 3, use printcom flush=True.

Aaron Hall
fonte
3

Somando-se os outros grandes respostas, podemos usar o Python loggingda biblioteca debug(), info(), warning(), error(), e critical()métodos. Citando os documentos para Python 3.7.4 ,

Existem três argumentos de palavra-chave nos kwargs que são inspecionados: exc_info que, se não for avaliado como falso, faz com que informações de exceção sejam adicionadas à mensagem de log.

O que isso significa é que você pode usar a loggingbiblioteca Python para gerar uma debug()ou outro tipo de mensagem, e a loggingbiblioteca incluirá o rastreamento de pilha em sua saída. Com isso em mente, podemos fazer o seguinte:

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)

E isso irá gerar:

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