在异常期间从所有堆栈帧中检索所有活动变量



我想在异常期间找出所有"调用"堆栈帧中的所有活动变量。

例如,请考虑以下示例来说明方案

import time
def mainFunc():
    now = time.time()
    author = "me"
    callClient()
def callClient():
    message = "Hello, World!"
    to = "stackoverflow.com"
    callNoOp()
    callException()
def callNoOp():
    subject = "Question in stack trace"
    print "No-op"
def callException():
    question = "What do I do?"
    raise Exception("Vishwanathan, vellai vendum!")
mainFunc()

例外渗透到callClient .我想看看此时的所有活动变量。 locals()会帮助我满足这一要求。

我还想知道的是message的价值,to callException()。以及引发异常时question的值。

我已经浏览了traceback模块文档。它似乎打印了堆栈跟踪,但没有打印这些堆栈帧中活动的变量。

回溯由一个对象链组成,通过 tb_next 属性链接在一起。每个回溯对象也通过tb_frame链接到帧,并且每个帧都有一个f_locals属性。

给定一个回溯对象,您可以使用以下命令打印链上的所有局部变量:

current = traceback
while current is not None:
    print current.tb_frame.f_locals
    current = current.tb_next

请参阅 Python 数据模型的标准类型层次结构部分(向下滚动到回溯对象)。

您还可以查看 inspect.trace() 实用程序函数,它将链解压缩为一系列命名元组:

import inspect
for frame_info in inspect.trace():
    print frame_info[0].f_locals

请确保显式清除对回溯的任何引用;由于回溯包含对当前命名空间的引用,因此在此处创建循环引用几乎是微不足道的。充其量,这会延迟清除这些引用,在最坏的情况下,具有__del__方法的对象涉及该循环,然后垃圾回收永远不会破坏该循环,并且您有内存泄漏。

我已经能够暂时找到解决方法,它看起来像这样。

def mainFunc():
    now = time.time()
    author = "me"
    try:
        callClient()
    except:
        tb = sys.exc_info()[2]
        while tb:
            print tb.tb_lineno, "@", tb.tb_frame.f_locals
            tb = tb.tb_next

最新更新