对于Python,有没有一种方法可以从发生异常的上下文中打印变量范围?

问题描述 投票:0回答:5

有没有办法从发生异常的上下文中打印变量范围?

例如:

def f():
    a = 1
    b = 2
    1/0

try:
    f()
except:
    pass # here I want to print something like "{'a': 1, 'b': 2}"
python exception
5个回答
23
投票

您可以使用函数

sys.exc_info()
来获取 except 子句中当前线程中发生的最后一个异常。这将是异常类型、异常实例和回溯的元组。回溯是框架的链表。这是解释器用来打印回溯的。它确实包含本地词典。

所以你可以这样做:

import sys

def f():
    a = 1
    b = 2
    1/0

try:
    f()
except:
    exc_type, exc_value, tb = sys.exc_info()
    if tb is not None:
        prev = tb
        curr = tb.tb_next
        while curr is not None:
            prev = curr
            curr = curr.tb_next
        print prev.tb_frame.f_locals

7
投票

您必须首先提取回溯,在您的示例中,类似这样的内容会打印它:

except:
    print sys.exc_traceback.tb_next.tb_frame.f_locals

我不确定 tb_next,我猜你必须经历完整的回溯,所以像这样(未经测试):

except:
    tb_last = sys.exc_traceback
    while tb_last.tb_next:
        tb_last = tb_last.tb_next
    print tb_last.tb_frame.f_locals

3
投票

也许您正在寻找 locals()globals()


2
投票

根据您的需要,有 2 种一般最佳实践。

只需编辑最少的代码即可打印变量

看看一些相关的包。对于简单的用法,你可以选择 traceback-with-variables (

pip install traceback-with-variables
),这是它的明信片

enter image description here

或者尝试tbvaccine,或better-exceptions,或任何其他包

以编程方式访问变量以在代码中使用它们

使用

inspect
模块

except ... as ...:
    x = inspect.trace()[-1][0].f_locals['x']

0
投票

Python 3 的零依赖解决方案:

import traceback

def format_traceback_with_locals(exc):
    traceback_segments = traceback.format_exception(exc)
    traceback_string = traceback_segments[0]
    tb = exc.__traceback__
    while tb is not None:
        locals_dict = {k: v for k, v in tb.tb_frame.f_locals.items() if not k.startswith("__")}
        traceback_segment = traceback.format_tb(tb)[0]
        traceback_string += traceback_segment
        traceback_string += "  -> local variables: " + str(locals_dict) + "\n"
        tb = tb.tb_next
    traceback_string += traceback_segments[-1]
    return traceback_string

用途:

try:
    ...
except Exception as e:
    print(format_traceback_with_locals(e))

这会迭代回溯段(标题,然后是每个帧,最后是异常)并在每个帧后打印相应的局部变量。

© www.soinside.com 2019 - 2024. All rights reserved.