考虑以下示例:
try:
raise ValueError('test')
except ValueError as err:
breakpoint() # at this point in the debugger, name 'err' is not defined
这里,在输入breakpoint后,调试器无法访问绑定到err
的异常实例:
$ python test.py
--Return--
> test.py(4)<module>()->None
-> breakpoint()
(Pdb) p err
*** NameError: name 'err' is not defined
为什么会出现这种情况?我如何访问异常实例?目前我正在使用以下解决方法,但感觉很笨拙:
try:
raise ValueError('test')
except ValueError as err:
def _tmp():
breakpoint()
_tmp()
# (lambda: breakpoint())() # or this one alternatively
有趣的是,使用这个版本,当向调试器上移一帧时,我也可以访问绑定的异常
err
:$ python test.py
--Return--
> test.py(5)_tmp()->None
-> breakpoint()
(Pdb) up
> test.py(6)<module>()
-> _tmp()
(Pdb) p err
ValueError('test')
通过dis
反汇编
接下来我将比较两个版本,一个直接使用breakpoint
,另一个把它封装在自定义函数_breakpoint
中:
def _breakpoint():
breakpoint()
try:
raise ValueError('test')
except ValueError as err:
breakpoint() # version (a), cannot refer to 'err'
# _breakpoint() # version (b), can refer to 'err'
dis
的输出类似,除了一些内存位置和函数名称当然也不同:
因此,必须是额外的堆栈帧使 pdb
能够引用绑定的异常实例。但是不清楚为什么会这样,因为在 except
块中任何东西都可以引用绑定的异常实例。