e.printStackTrace odpowiednik w pythonie

207

Wiem, że print(e)(gdzie e jest wyjątkiem) drukuje występujący wyjątek, ale próbowałem znaleźć odpowiednik języka Java w języku Python, e.printStackTrace()który dokładnie śledzi wyjątek od tego, w jakiej linii wystąpił, i drukuje cały jego ślad.

Czy ktoś mógłby mi powiedzieć odpowiednik e.printStackTrace()Pythona?

koool
źródło

Odpowiedzi:

280
import traceback
traceback.print_exc()

Robiąc to wewnątrz except ...:bloku, automatycznie użyje bieżącego wyjątku. Więcej informacji można znaleźć na stronie http://docs.python.org/library/traceback.html .

ThiefMaster
źródło
10
Jeśli pracujesz w jakimś pojemniku, takim jak Jython i dlatego nie możesz po prostu wydrukować śladu, możesz format_exczamiast tego uzyskać ciąg.
SeldomNeedy
116

Jest też logging.exception.

import logging

...

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

Wynik:

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

(Od http://blog.tplus1.com/index.php/2007/09/28/the-python-logging-module-is-much-better-than-print-statements/ poprzez Jak wydrukować pełny traceback bez wstrzymanie programu? )

david.libremone
źródło
Jakie są zalety / wady tego w porównaniu do traceback.print_exc()?
Nathan
18

e.printStackTrace odpowiednik w pythonie

W Javie wykonuje to następujące czynności ( dokumenty ):

public void printStackTrace()

Drukuje ten możliwy do rzucania i jego ślad do standardowego strumienia błędów ...

Jest to używane w następujący sposób:

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

W Javie strumień błędu standardowego nie jest buforowany, więc dane wyjściowe są dostarczane natychmiast.

Ta sama semantyka w Pythonie 2 to:

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

W Pythonie 3 możemy uzyskać śledzenie bezpośrednio z obiektu wyjątku (który prawdopodobnie lepiej zachowuje się w przypadku kodu wątkowego). Ponadto, stderr jest buforowany w linii , ale funkcja print otrzymuje argument opróżnienia, więc zostanie on natychmiast wydrukowany do stderr:

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

Wniosek:

Dlatego w Pythonie 3, traceback.print_exc()chociaż używa sys.stderr domyślnie , buforowałby dane wyjściowe i możliwe, że je utracisz. Tak, aby uzyskać jak równoważnych semantyki, jak to możliwe, w Pythonie 3, korzystać printz flush=True.

Aaron Hall
źródło
3

Dodanie do innych wielkich odpowiedzi, możemy użyć pytona loggingbibliotecznych debug(), info(), warning(), error()i critical()metod. Cytując z dokumentacji dla Python 3.7.4 ,

W kwargach, które są sprawdzane, występują trzy argumenty słów kluczowych: exc_info, które, jeśli nie zostanie ocenione jako fałszywe, powodują dodanie informacji o wyjątku do komunikatu logowania.

Oznacza to, że możesz użyć loggingbiblioteki Python do wyprowadzenia komunikatu debug()lub innego rodzaju komunikatu, a loggingbiblioteka uwzględni ślad wyjściowy stosu. Mając to na uwadze, możemy wykonać następujące czynności:

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)

I wyświetli:

'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
źródło