e.printStackTrace эквивалент в Python

208

Я знаю, что print(e)(где e - это исключение) печатает возникшее исключение, но я пытался найти Python-эквивалент Java, e.printStackTrace()который точно отслеживает исключение до той строки, в которой оно произошло, и печатает весь его след.

Может кто-нибудь сказать, пожалуйста, эквивалент e.printStackTrace()в Python?

koool
источник

Ответы:

281
import traceback
traceback.print_exc()

Делая это внутри except ...:блока, он автоматически использует текущее исключение. См. Http://docs.python.org/library/traceback.html для получения дополнительной информации.

ThiefMaster
источник
10
Если вы работаете внутри какого-то контейнера, такого как Jython, и поэтому не можете просто напечатать трассировку, вы можете format_excвместо этого получить строку.
SeldomNeedy
116

Есть также logging.exception.

import logging

...

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

Вывод:

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

(Из http://blog.tplus1.com/index.php/2007/09/28/the-python-logging-module-is-much-better-than-print-statements/ через Как напечатать полный обратный вызов без остановка программы? )

david.libremone
источник
Каковы преимущества / недостатки этого по сравнению traceback.print_exc()?
Натан
19

e.printStackTrace эквивалент в Python

В Java это делает следующее ( документы ):

public void printStackTrace()

Печатает этот throwable и его backtrace к стандартному потоку ошибок ...

Это используется так:

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

В Java поток стандартных ошибок не буферизуется, поэтому вывод поступает немедленно.

Та же семантика в Python 2:

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

В Python 3 мы можем получить трассировку непосредственно от объекта исключения (который, вероятно, ведет себя лучше для многопоточного кода). Кроме того, stderr буферизуется строкой , но функция print получает аргумент flush, так что это будет немедленно выведено в stderr:

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

Вывод:

Поэтому в Python 3, traceback.print_exc()хотя он и используется sys.stderr по умолчанию , буферизуется вывод, и вы можете его потерять. Таким образом, чтобы получить как можно более эквивалентную семантику, в Python 3 используйте printwith flush=True.

Аарон Холл
источник
3

Добавление других больших ответов, мы можем использовать в Python loggingбиблиотечной debug(), info(), warning(), error()и critical()методу. Цитирование из документации по Python 3.7.4 ,

В kwargs проверяются три ключевых аргумента: exc_info, который, если он не оценивается как ложный, вызывает добавление информации об исключении в сообщение регистрации.

Это означает, что вы можете использовать loggingбиблиотеку Python для вывода сообщений debug()другого типа, и loggingбиблиотека будет включать в свой вывод трассировку стека. Имея это в виду, мы можем сделать следующее:

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)

И это выведет:

'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
источник