如何从pdb/pdbpp“跳转”运行实例的任意python生成器的框架?

2024-06-17 12:03:44 发布

您现在位置:Python中文网/ 问答频道 /正文

假设您有这个生成器:

def gen():
  for i in range(10):
    yield i-5

然后你会这样做:

try :
  for a in gen():
    print(5 / a) # Obviously, it will crash on a=0
except:
  import pdb; pdb.xpm() # I'm using pdbpp actually

一旦调试器启动(无论是香草pdb还是pdbpp),是否有一种方法可以在生成器内部“进入”(转到其执行框架),检查其内部变量,而不中断程序(我的意思是,只是“观察”并能够像调试器从未启动一样执行)

编辑

如果有帮助的话,在真实代码中,我仍然有一个对生成器的引用,所以它“更”像这样:

g = gen()
try :
  for a in g:
    print(5 / a) # Obviously, it will crash on a=0
except:
  import pdb; pdb.xpm() # I'm using pdbpp actually

Tags: inimportforonitcrashwillpdb
1条回答
网友
1楼 · 发布于 2024-06-17 12:03:44

使用类似您最初发布的代码,您无法检查生成器

在您启动调试器时,生成器已运行。对生成器的唯一引用是在发生生成器上的循环的帧对象的值堆栈上,当异常传播时,该引用将被清除。下面是一个演示这一事实的程序:

class DelPrintIterator:
    def __iter__(self):
        return self
    def __next__(self):
        return 1
    def __del__(self):
        print('Deleting iterator')

try:
    for i in DelPrintIterator():
        1/0
except ZeroDivisionError:
    print('Too late')

这张照片

Deleting iterator
Too late

显示在except块中的任何代码运行之前,迭代器变得不可访问


现在,带有对生成器的引用,类似于

g = gen()
try:
    for a in gen():
        print(5 / a)
except ZeroDivisionError:
    ...

然后。。。嗯,我不知道有哪个调试器会让你在生成器的堆栈框架不在堆栈上时“进入”它,但是你可以用g.gi_frame手动检索框架,然后开始查看调试器使用的相同属性,比如frame.f_localsframe.f_lineno。(框架对象属性列在^{}模块文档中。)它不如调试器的接口方便,但相同的信息仍然存在

相关问题 更多 >