首页 > 解决方案 > 在 Python 中以编程方式执行用户输入的 pdb 或 ipdb 命令

问题描述

我正在使用 PyQt 应用程序,因此在开始调试之前,在 Python 文件中,我有pyqtRemoveInputHook()停止事件循环的行,然后ipdb.set_trace(). 这将通过终端进入交互式调试会话。完成调试后,我需要手动输入终端c; pyqtRestoreInputHook()以继续运行程序并恢复事件循环。c告诉ipdbpdb继续,被pyqtRestoreInputHook()解释为 Python 代码。虽然这不是太大的麻烦,但我想以某种方式创建一个函数,允许 python 命令告诉ipdb或者pdb给定的字符串是伪键盘命令。

换句话说,我试图找到一个基本上ipdb.run_user_input(my_string)可以my_string是任何正常ipdbpdb函数的函数,如next, c, step,list等。

谢谢!

标签: python-3.xpdbipdb

解决方案


我一直在寻找类似的东西,但 pdb 似乎不允许您以编程方式运行一系列 pdb 命令。

但是,它确实允许您从文件中读取一系列 pdb 命令.pdbrc,这些命令会在进入任何 pdb 会话时立即执行。

幸运的是,根据文档

run* 函数和 set_trace() 是用于实例化 Pdb 类和调用同名方法的别名。

...换句话说,对 pdb 的每次调用似乎都实例化了该类的一个新实例,readrc参数默认为 true,因此您可以.pdbrc在调用之前创建一个新文件,新文件将被拾取并执行。

因此,在调用 pdb.set_trace 之前在当前目录中写入一个.pdbrc文件就足够了,其中包含您感兴趣的命令序列。例如

import pdb;

with open( '.pdbrc', 'w') as f: 
    print( "print('Hello from pdbrc')", file = f )
    print( "continue", file = f )

pdb.set_trace()

with open( '.pdbrc', 'w') as f:
    print( "print('Hello again!')", file = f )

pdb.set_trace()

在上面的例子中,第一个pdb.set_trace()应该打印“Hello from pdbrc”并立即继续程序执行,然后第二个pdb.set_trace()应该打印“Hello again!” 并留在 pdb 环境中。


警告:如果您依赖的主目录中有一个现有的 .pdbrc 文件,请确保您不会覆盖它(例如,确保您有备份)。


UPDATE事实证明,您可以以编程方式附加到 rc 行,这消除了完全在磁盘上创建文件的需要。请注意,您不能pdb直接在模块上执行此操作,您需要先创建一个Pdb类实例。

import pdb
pdb = pdb.Pdb()   # or pdb = pdb.Pdb( readrc = False )  if you want to ignore your existing .pdbrc
pdb.rcLines.append( "print('Hellooo')" )
pdb.rcLines.append( "continue" )
pdb.set_trace()

这样做的一个优点是,除非您使用该readrc = False参数调用,否则您现有的 .pdbrc 文件将得到尊重,并且您以编程方式附加的任何命令都将有效地附加到 pdbrc 派生的命令中。

但是,请注意,由于某种原因,在通过此pdb 实例成功进行第一次跟踪后,pdb.rcLines列表将被清除,您应该使用所需的任何新命令重新填充它,以便从此实例执行第二次跟踪。


推荐阅读