在断点处停止时执行任意代码...我可以欺骗 Python 使其认为代码是在该帧的实际本地范围内执行的吗?
Python 调试器 pdb 允许这样做。例如,假设您正在调试文件tests/scopeTest.py,并且您的程序中有以下行,该变量尚未在程序本身中声明:
print (NOT_DEFINED_IN_PROGRAM)
这样运行代码python tests/scopeTest.py 会导致:
NameError: name 'NOT_DEFINED_IN_PROGRAM' is not defined
现在您想在调试器中停止在该行时定义该变量,并让程序继续执行,使用该变量,就像它一直在程序中定义一样。换句话说,您希望在该范围内实现更改,以便您可以继续执行该更改永久。其实是可以的:
$ python -m pdb tests/scopeTest.py
> /home/user/tests/scopeTest.py(1)<module>()
-> print (NOT_DEFINED_IN_PROGRAM)
(Pdb) 'NOT_DEFINED_IN_PROGRAM' in locals()
False
(Pdb) NOT_DEFINED_IN_PROGRAM = 5
(Pdb) 'NOT_DEFINED_IN_PROGRAM' in locals()
True
(Pdb) step
5
Pdb 通过其default 函数中的compile 和exec 执行此操作,相当于:
code = compile(line + '\n', <stdin>, 'single')
exec(code, self.curframe.f_globals, self.curframe_locals)
其中self.curframe 是一个特定的框架。现在,self.curframe_locals 不是self.curframe.f_locals,因为正如setup 函数所说:
# The f_locals dictionary is updated from the actual frame
# locals whenever the .f_locals accessor is called, so we
# cache it here to ensure that modifications are not overwritten.
self.curframe_locals = self.curframe.f_locals
希望对您有所帮助,这就是您的意思!
请注意,即便如此,您是否希望,例如,将正在调试的程序上下文中的函数替换为猴子补丁版本,例如:
newGlobals['abs'] = myCustomAbsFunction
exec(code, newGlobals, locals)
myCustomAbsFunction 的范围不是用户程序,而是定义该函数的上下文,即调试器!也有一种方法可以解决这个问题,但由于没有特别要求,所以暂时将其作为练习留给读者。 ^__^