e.printStackTrace在python中的等效

我知道print(e)(其中e是异常)打印发生的异常 但是,我试图找到Java的e.printStackTrace()的python等效物,它精确地跟踪异常发生的行,并打印它的整个跟踪

有人能告诉我Python中e.printStackTrace()的等价物吗?

152089 次浏览
import traceback
traceback.print_exc()

当在except ...:块中执行此操作时,它将自动使用当前异常。更多信息请参见http://docs.python.org/library/traceback.html

还有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/如何在不停止程序的情况下打印完整的回溯?)

e.printStackTrace在python中的等效

在Java中,它执行以下操作(文档):

public void printStackTrace()

打印这个可抛出对象及其回溯到标准错误流…

它是这样使用的:

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

在python3中,我们可以直接从异常对象获取回溯(这可能对线程代码表现更好)。 还有Stderr是行缓冲的,但是print函数得到 flush参数,因此这将立即打印到stderr:

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

结论:

因此,在python3中,traceback.print_exc()虽然使用了sys.stderr 默认情况下,但会缓冲输出,你可能会丢失它。因此,为了获得尽可能等效的语义,在Python 3中,使用printflush=True

除了其他很棒的答案,我们还可以使用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'