在 Python 中以编程方式执行用户输入的 pdb 或 ipdb 命令

Dus*_*tin 6 python-3.x pdb ipdb

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

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

谢谢!

Tas*_*nou 2

我一直在寻找类似的东西,但 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()
Run Code Online (Sandbox Code Playgroud)

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


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


更新事实证明,您可以以编程方式附加到 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()
Run Code Online (Sandbox Code Playgroud)

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

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