traceback.print_exc()显示不完整的堆栈跟踪

时间:2017-02-19 14:56:37

标签: python

回溯模块非常适合捕获和处理异常,但在下面的示例中,它似乎从最近的异常中捕获了一个不完整的堆栈。

考虑两个文件,一个说“mymod.py”:

import sys, traceback

def func():
    try:
        otherfunc()
    except:
        raise
        #traceback.print_exc()

def otherfunc():
    raise Exception( 'fake' )

另一个人说“myfile.py”:

from mymod import *
func()

运行myfile.py给出:

Traceback (most recent call last):
  File "myfile.py", line 2, in <module>
    func()
  File "/Users/rrdrake/temp/mymod.py", line 5, in func
    otherfunc()
  File "/Users/rrdrake/temp/mymod.py", line 11, in otherfunc
    raise Exception( 'fake' )

现在更改mymod.py以注释掉“raise”并取消注释print_exc行。然后我们得到

Traceback (most recent call last):
  File "/Users/rrdrake/temp/mymod.py", line 5, in func
    otherfunc()
  File "/Users/rrdrake/temp/mymod.py", line 11, in otherfunc
    raise Exception( 'fake' )
Exception: fake

请注意,在重新提升时,print_exc()不包含myfile.py框架。如何使print_exc()包含原始调用框架?

请注意,如果我在except块中添加了traceback.print_stack(),它确实包含myfile.py框架,因此信息似乎可用。

1 个答案:

答案 0 :(得分:2)

在您的第一种情况下,raise调用中的异常会在脚本的顶层冒泡。 Python调用sys.excepthook(),它显示完整的回溯。

在你的第二种情况下,异常被捕获并且print_exc()用于打印异常,这在调用函数(在你的情况下为otherfunc())停止,所以你不能得到完整的追溯。

您可以使用自己的回溯/异常打印功能来更改它, 这些方面的东西:

def print_full_stack(tb=None):
    if tb is None:
        tb = sys.exc_info()[2]

    print 'Traceback (most recent call last):'
    for item in reversed(inspect.getouterframes(tb.tb_frame)[1:]):
        print ' File "{1}", line {2}, in {3}\n'.format(*item),
        for line in item[4]:
            print ' ' + line.lstrip(),
    for item in inspect.getinnerframes(tb):
        print ' File "{1}", line {2}, in {3}\n'.format(*item),
        for line in item[4]:
            print ' ' + line.lstrip(),

只需将traceback.print_exc()替换为print_full_stack()即可。此函数涉及inspect模块以获取代码帧。

您可以阅读此博客以获取更多信息:http://blog.dscpl.com.au/2015/03/generating-full-stack-traces-for.html

请注意,上面文章中的代码有一些缩进错误......