考虑以下示例:
try:
raise ValueError('test')
except ValueError as err:
breakpoint() # at this point in the debugger, name 'err' is not defined
在这里,在 breakpoint 之后输入,调试器无权访问绑定(bind)到 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
有趣的是,使用这个版本,我还可以访问绑定(bind)异常 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
的附加堆栈帧引用绑定(bind)的异常实例。但是不清楚为什么会这样,因为在 except
阻止任何东西都可以引用绑定(bind)的异常实例。
最佳答案
breakpoint()
不是断点,因为它会在此函数调用的确切位置停止执行。相反,它是 import pdb; pdb.set_trace()
的简写。这将在下一行代码处停止执行(它在幕后调用 sys.settrace
)。由于 except
内没有更多代码块,执行将在该 block 退出后停止,因此名称 err
已被删除。通过在 except
之后添加一行代码可以更清楚地看到这一点。堵塞:
try:
raise ValueError('test')
except ValueError as err:
breakpoint()
print()
这给出了以下内容:$ python test.py
> test.py(5)<module>()
-> print()
这意味着解释器即将执行 print()
第 5 行中的语句,并且它已经执行了它之前的所有内容(包括删除名称 err
)。当使用另一个函数来包装
breakpoint()
然后解释器将在 return
处停止执行。该函数的事件,因此 except
block 尚未退出(err
仍然可用):$ python test.py
--Return--
> test.py(5)<lambda>()->None
-> (lambda: breakpoint())()
except
的退出也可以通过添加一个额外的 pass
来延迟 block 。 breakpoint()
之后的声明:try:
raise ValueError('test')
except ValueError as err:
breakpoint()
pass
这导致:$ python test.py
> test.py(5)<module>()
-> pass
(Pdb) p err
ValueError('test')
请注意 pass
必须放在单独的行上,否则将被跳过:$ python test.py
--Return--
> test.py(4)<module>()->None
-> breakpoint(); pass
(Pdb) p err
*** NameError: name 'err' is not defined
注意 --Return--
这意味着解释器已经到达模块的末尾。
关于python - except 子句中的断点无权访问绑定(bind)异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62796591/