Skip to main content
 首页 » 编程设计

python之如何从 pdb 控制台进入任意生成器函数调用

2025年05月04日11落叶无声

我有一个行为不正常的生成器函数,我想从 pdb 控制台调用它,然后逐步执行它的每次迭代以查看它的哪一部分是错误的。我希望我能

(Pdb) !pdb.runcall(broken_function, with_arg) 

但是因为这个函数是一个生成器,所以我得到的只是

<generator object broken_function at 0x2badc30> 

有没有人知道我现在可以做什么?

编辑:我应该早点说清楚:我当然想在相关循环中设置一个断点,但我正在从一个(对我而言)只读文件系统运行代码,这使这变得不切实际。

请您参考如下方法:

编辑:简短版:

选项:

  1. 使用 pdb.run('my_module.my_method()') 定位您的函数并单步执行生成器。

  2. 将 pdb 作为脚本调用 python -m pdb my_script.py。

使用测试文件 yippy_dog.py:

def yippy_dog(): 
    for i in range(10): 
        print("YIP YIP!") 
 
yippy_dog() 

要从 pdb 控制台定位生成器,导入所需的模块,然后在调用相关方法时调用 .run():

>>> import pdb 
>>> import yippy_dog 
YIP YIP! 
~~~ 
YIP YIP! 
YIP YIP! 
>>> pdb.run('yippy_dog.yippy_dog()') 
> <string>(1)<module>() 
(Pdb) s 
--Call-- 
> /private/tmp/yippy_dog.py(1)yippy_dog() 
-> def yippy_dog(): 
(Pdb) s 
> /private/tmp/yippy_dog.py(2)yippy_dog() 
-> for i in range(10): 
(Pdb) s 
> /private/tmp/yippy_dog.py(3)yippy_dog() 
-> print("YIP YIP!") 
(Pdb) s 
YIP YIP! 
> /private/tmp/yippy_dog.py(2)yippy_dog() 
-> for i in range(10): 
(Pdb) s 
> /private/tmp/yippy_dog.py(3)yippy_dog() 
-> print("YIP YIP!") 
(Pdb) s 
YIP YIP! 
> /private/tmp/yippy_dog.py(2)yippy_dog() 
-> for i in range(10): 
(Pdb) s 
> /private/tmp/yippy_dog.py(3)yippy_dog() 
-> print("YIP YIP!") 
(Pdb) s 
YIP YIP! 
> /private/tmp/yippy_dog.py(2)yippy_dog() 
-> for i in range(10): 
(Pdb) 

要通过从命令行将 pdb 作为脚本调用的生成器运行,请调用 pdb 模块并单步执行到相关框架:

$ python -m pdb yippy_dog.py 
> /private/tmp/yippy_dog.py(1)<module>() 
-> def yippy_dog(): 
(Pdb) step 
> /private/tmp/yippy_dog.py(5)<module>() 
-> yippy_dog() 
(Pdb) step 
--Call-- 
> /private/tmp/yippy_dog.py(1)yippy_dog() 
-> def yippy_dog(): 
(Pdb) step 
> /private/tmp/yippy_dog.py(2)yippy_dog() 
-> for i in range(10): 
(Pdb) step 
> /private/tmp/yippy_dog.py(3)yippy_dog() 
-> print("YIP YIP!") 
(Pdb) step 
YIP YIP! 
> /private/tmp/yippy_dog.py(2)yippy_dog() 
-> for i in range(10): 
(Pdb) step 
> /private/tmp/yippy_dog.py(3)yippy_dog() 
-> print("YIP YIP!") 
(Pdb) step 
YIP YIP! 
> /private/tmp/yippy_dog.py(2)yippy_dog() 
-> for i in range(10): 

当然,您可以通过在生成器中放置 set_trace() 来手动强制设置断点,但这需要在目标代码中进行修改/放置调试,这可能并不理想。