Python pdb(调试器)disp等价物?

Python pdb(调试器)disp等价物?,python,debugging,pdb,Python,Debugging,Pdb,gdb中是否有相当于disp的pdb 例如,当我使用gdb调试C时,我可以通过键入以下内容在代码的每个“步骤”上打印变量: disp var 当我使用pdb调试python时,我希望有类似的功能,但似乎没有,python pdb文档似乎没有提供替代方案-但这似乎是一个奇怪的遗漏?在pdb调试期间,您可以键入普通python代码,除了一个字母的命令之外,只需使用print var就可以了。下面的代码使用Python内省功能向PDB模块0添加两个新命令 只需将给定函数及其调用放在一个单独的模块中,

gdb中是否有相当于
disp
的pdb

例如,当我使用gdb调试C时,我可以通过键入以下内容在代码的每个“步骤”上打印变量:

disp var

当我使用pdb调试python时,我希望有类似的功能,但似乎没有,python pdb文档似乎没有提供替代方案-但这似乎是一个奇怪的遗漏?

在pdb调试期间,您可以键入普通python代码,除了一个字母的命令之外,只需使用
print var
就可以了。

下面的代码使用Python内省功能向PDB模块0添加两个新命令 只需将给定函数及其调用放在一个单独的模块中,并在开始调试之前导入此模块-您应该让'disp'和'undisp'命令向变量添加和收回手表

它通过monkeypatching Python的pdb模块工作,该模块是用纯Python编写的

# -*- coding: utf-8 -*-

def patch_pdb():
    import pdb

    def wrap(func):
        def new_postcmd(self, *args, **kw):
            result = func(self, *args, **kw)
            if hasattr(self, "curframe") and self.curframe and hasattr(self, "watch_list"):
                for arg in self.watch_list:
                    try:
                        print >> self.stdout, "%s: %s"% (arg, self._getval(arg)) + ", ", 
                    except: 
                        pass
                self.stdout.write("\n")
            return result #func(self, *args, **kw)

        return new_postcmd

    pdb.Pdb.postcmd = wrap(pdb.Pdb.postcmd)

    def do_disp(self, arg):
        if not hasattr(self, "watch_list"):
            self.watch_list = []
        self.watch_list.append(arg)

    pdb.Pdb.do_disp = do_disp

    def do_undisp(self, arg):
        if hasattr(self, "watch_list"):
            try:
                self.watch_list.remove(arg)
            except:
                pass

    pdb.Pdb.do_undisp = do_undisp

patch_pdb()

if __name__ == "__main__":
    # for testing
    import pdb; pdb.set_trace()
    a = 0
    for i in range(10):
        print i
        a += 2

不幸的是,我只能让它在执行最后一个命令之前显示变量的状态。(我尝试了一点,但是monkeypatching的bdb模块,这是Pdb的基础,似乎没有很好的工作)。您可以尝试更改pdb.pdb、bdb.bdb或cmd.cmd中由
wrap
修饰的方法,以查找在调试的帧状态更改后调用的方法。

您可以设置一些别名来执行此操作:

别名n next;;p变量
别名s步骤;;p变量
打印整个变量名列表是留给读者的一个练习。不幸的是,这样做意味着当您向调试器发送一个空行时,它执行的“最后一个命令”是
p var
,而不是,例如
n
。如果您想解决这个问题,那么可以使用这组有点粗糙的Pdb命令:

!全局堆栈;从检查导入堆栈作为\uuuu堆栈
!全球Pdb;从pdb将pdb作为_pdb导入
!全球pdb__pdb=[[uuuu framerec[0].f_locals.get(“pdb”)或uu framerec[0].f_locals.get(“self”)用于uu堆栈中的uu framerec()if([uuu framerec[0].f_ulocals.get(“pdb”)或u framerec[0].f_ulocals.get(“self”)。u类uuu===[uu pdb 1]
别名s步骤;;p变量__pdb.lastcmd=“!\uu pdb.cmdqueue.append('s')”
别名n next;;p变量__pdb.lastcmd=“!\uu pdb.cmdqueue.append('n')”

这是否意味着每次我点击
s
n
时,pdb都会自动重新打印
var
?不确定是否会,对我来说,似乎与键入
p var
相同。问题不在于如何使用调试器打印变量,而在于如何更有效地使用pdb…抱歉-不是-这只打印一次变量。也许ipdb有一些替代功能作为替代,如果您喜欢漂亮的UI,您可能希望使用。