如果在Python程序中检测到错误,那么在堆栈跟踪旁边生成包括全局变量和局部变量的上下文转储会很有用。
异常处理程序是否有某种方式可以访问全局变量和局部变量,而不必在raise异常语句中包含globals()和locals()?
以下示例代码:
# Python 3.3 code
import sys
class FunError(Exception):
pass
def fun(x): # a can't be 2 or 4
if x in [2, 4]:
raise FunError('Invalid value of "x" variable')
else:
return(x ** 2)
try:
print(fun(4))
except Exception as exc:
# Is value of 'x' variable at time of exception accessible here ?
sys.exit(exc)
基于答案产生的异常代码:
...
except FunError as exc:
tb = sys.exc_info()[2] # Traceback of current exception
while tb.tb_next: # Dig to end of stack
tb = tb.tb_next # Next level
print('Local at raise exception: x =', tb.tb_frame.f_locals['x']) # Wanted data
sys.exit(exc)
...
答案 0 :(得分:4)
堆栈跟踪是帧对象的链接序列;每个帧对象都引用该帧的全局变量和局部变量。
tb_frame
属性,这是“当前”框架。tb_next
属性,指向堆栈中 next traceback对象的链接。f_globals
和f_locals
属性,两者都是字典。 inspect
module documentation可以方便地概述在回溯和框架对象上找到的属性。
您可能需要查看traceback
module;它提供了一个更高级别的API来操作和显示回溯。
答案 1 :(得分:1)
比使用堆栈帧更容易和更直接的是知道在加注时你对感兴趣的变量在范围内。
raise FunError('Invalid argument', x)
此外,你永远不应该捕捉异常,你应该尽可能地缩小:
except FunError as e:
print('I will not submit %d to fun()' % e[1])
是首选,因为except Exception
会捕获(其中包括)MemoryError或IndentationError,这两者都无法解决。