我可以获取引发异常的Python函数的局部变量吗?

问题描述 投票:22回答:6

我正在为项目编写自定义日志系统。如果一个函数抛出异常,我想记录它的局部变量。是否可以从捕获异常的except块中访问提升函数的局部变量?例如:

def myfunction():
    v1 = get_a_value()
    raise Exception()

try:
    myfunction()
except:
    # can I access v1 from here?
python exception-handling
6个回答
31
投票

如果知道异常处理代码将需要的值传递给异常,这通常是一种更干净的设计。但是,如果您正在编写调试器或类似的东西,则需要在不事先知道变量的情况下访问变量,则您可以在引发异常的上下文中访问任意变量: >def myfunction(): v1 = get_a_value() raise Exception() try: myfunction() except: # can I access v1 from here? v1 = inspect.trace()[-1][0].f_locals['v1']

trace函数的功能及其处理的traceback对象的格式在inspect module documentation中描述。

inspect
您可以在框架对象中查找局部变量,可以从def myFunction() v1 = get_a_value() raise Exception(v1) try: myFunction() except Exception, e: v1 = e.args[0] 中获得。

sys.exc_info

根据异常在堆栈中的深度,您必须包括适当数量的>>> import sys
>>> def f(a):
...     b = a - 1
...     print 1.0 / b
...
>>> try:
...     f(1)
... except Exception, e:
...     print sys.exc_info()[2].tb_next.tb_frame.f_locals
...
{'a': 1, 'b': 0}

是的,如果这是您自己的异常类型。像这样:

tb_next

>>> class MyExn(Exception): ... def __init__(self, val): ... self.val = val ... def __str__(self): ... print "something wrong with:", str(self.val) ... >>> def foo(): ... val = 42 ... raise MyExn(val) ... >>> foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in foo __main__.MyExnsomething wrong with: 42 >>> # Or in a try block: >>> try: ... foo() ... except MyExn as e: ... print e.val ... 42 >>>
例如,在不使用try: myfunction() except: import sys type, value, tb = sys.exc_info() while tb.tb_next: tb = tb.tb_next frame = tb.tb_frame print frame.f_locals['v1'] 且不使用“检查”之类的库的情况下用于“处理”异常。

但是,我认为如果要“实际”处理异常,最好使用raise Exception(some_def_var)之类的东西。 raise Exception(some_def_var)

See @capfredf answer


3
投票
inspect

3
投票
您可以在框架对象中查找局部变量,可以从def myFunction() v1 = get_a_value() raise Exception(v1) try: myFunction() except Exception, e: v1 = e.args[0] 中获得。

1
投票
是的,如果这是您自己的异常类型。像这样:

0
投票
>>> class MyExn(Exception): ... def __init__(self, val): ... self.val = val ... def __str__(self): ... print "something wrong with:", str(self.val) ... >>> def foo(): ... val = 42 ... raise MyExn(val) ... >>> foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in foo __main__.MyExnsomething wrong with: 42 >>> # Or in a try block: >>> try: ... foo() ... except MyExn as e: ... print e.val ... 42 >>>

0
投票
例如,在不使用try: myfunction() except: import sys type, value, tb = sys.exc_info() while tb.tb_next: tb = tb.tb_next frame = tb.tb_frame print frame.f_locals['v1'] 且不使用“检查”之类的库的情况下用于“处理”异常。
© www.soinside.com 2019 - 2024. All rights reserved.