捕获异常时,如何获取前一个帧的类型、文件和行号?

7 投票
3 回答
529 浏览
提问于 2025-04-15 13:40

这个问题中,我现在正在处理错误,想要更深入一点。也就是说,我调用一个函数,这个函数又调用了另一个更大的函数,而我想知道在那个更大的函数中出错的具体位置,而不是在较小的函数中。举个具体的例子,代码是:

import sys, os

def workerFunc():
    return 4/0

def runTest():
    try:
        print workerFunc()
    except:
        ty,val,tb = sys.exc_info()
        print "Error: %s,%s,%s" % (
            ty.__name__,
            os.path.split(tb.tb_frame.f_code.co_filename)[1],
            tb.tb_lineno)

runTest()

输出是:

Error: ZeroDivisionError,tmp2.py,8

但是第8行是“print workerFunc()”——我知道这一行出错了,但我想知道出错前的那一行:

Error: ZeroDivisionError,tmp2.py,4

3 个回答

2

你需要找到错误信息的最底部,所以你需要一直循环,直到没有更多的调用记录为止。这样做可以帮助你找到你想要的记录:

while tb.tb_next:
    tb = tb.tb_next

在 sys.exc_info 之后使用这个。这可以找到错误,无论它发生在多少层调用记录中。

3

tb.tb_next 是你的好帮手:

import sys, os

def workerFunc():
    return 4/0

def runTest():
    try:
        print workerFunc()
    except:
        ty,val,tb = sys.exc_info()
        print "Error: %s,%s,%s" % (
            ty.__name__,
            os.path.split(tb.tb_frame.f_code.co_filename)[1],
            tb.tb_next.tb_lineno)

runTest()

不过,traceback模块 能做的事情可多着呢:

import traceback

def workerFunc():
    return 4/0

def runTest():
    try:
        print workerFunc()
    except:
        print traceback.format_exc()

runTest()
4

添加一行:

    tb = tb.tb_next

就在你调用 sys.exc_info 之后。

可以在文档中查看 这里,在“追踪对象”部分。

撰写回答