在Python中,与e.printStackTrace等价的方法是什么?

256
我知道print(e)(其中e是一个异常)会打印出发生的异常,但是我在尝试找到Python中Java的e.printStackTrace()等效物,能够精确地追踪异常发生的行并打印出整个跟踪过程。
请问有人可以告诉我Python中e.printStackTrace()的等效物吗?
4个回答

335

12
如果您正在某种容器内工作,例如 Jython,因此无法直接打印跟踪信息,则可以改用 format_exc 以获取字符串形式的信息。 - Seldom 'Where's Monica' Needy

140

还有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/,经由如何在Python中打印完整的回溯信息而不停止程序?)


4
相较于 traceback.print_exc(),这种方法有哪些优缺点? - Nathan majicvr.com
3
最大的优势是您可以通过配置记录器来控制想要查看的内容和位置。例如,您可以在生产环境中使用它将日志发送到日志服务,以便更轻松地修复难以重现的问题。 - Governa

25
e.printStackTrace在Python中的等效方法 在Java中,这个命令会做以下的事情(docs):
public void printStackTrace()

Prints this throwable and its backtrace to the standard error stream...

这是这样使用的:

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中,为了获得尽可能等效的语义,请使用printflush=True


11

除了其他很好的答案之外,我们可以使用Python的logging库的debug()info()warning()error()critical()方法。引用Python 3.7.4文档中的一段话:

kwargs 中有三个关键字参数需要检查:exc_info,如果它不为 false,则会将异常信息添加到日志消息中。

这意味着,您可以使用Python的logging库输出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'

3
logger.error(str(e), exc_info=True) 可以更好地表达为 logger.exception() - Joe Sadoski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接