你如何看pdb中的variables

我正在debugging一个python脚本,我想看一个variables的变化(就像你可以在gdb中看内存地址一样)。 有没有办法做到这一点?

这是一个很棘手的方式与pdb做到这一点。 这些命令可以放在你的~/.pdbrc ,每次使用pdb时自动加载。

 !global __currentframe, __stack; from inspect import currentframe as __currentframe, stack as __stack !global __copy; from copy import copy as __copy !global __Pdb; from pdb import Pdb as __Pdb !global __pdb; __pdb = [__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self") for __framerec in __stack() if (__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self")).__class__ == __Pdb][-1] alias _setup_watchpoint !global __key, __dict, __val; __key = '%1'; __dict = __currentframe().f_locals if __currentframe().f_locals.has_key(__key) else __currentframe().f_globals; __val = __copy(%1) alias _nextwatch_internal next;; !if __dict[__key] == __val: __pdb.cmdqueue.append("_nextwatch_internal %1") alias _stepwatch_internal step;; !if __dict[__key] == __val: __pdb.cmdqueue.append("_stepwatch_internal %1") alias nextwatch __pdb.cmdqueue.extend(["_setup_watchpoint %1", "_nextwatch_internal"]) alias stepwatch __pdb.cmdqueue.extend(["_setup_watchpoint %1", "_stepwatch_internal"]) 

这增加了两个命令, nextwatchstepwatch ,每个命令都将variables名称varname作为参数。 如果可能的话,他们将为varname创build当前帧的局部variables的浅拷贝,并分别继续执行nextstep直到名称指向哪个变化。

这在CPython 2.7.2中有效,但依赖于一些pdb内部,所以它可能会在其他地方打破。

为了在你遇到断点时观察一个variables,你可以使用commands命令。 例如,在some_variable点1时打印some_variable ( 来自pdb doc的规范示例 )。

 (Pdb) commands 1 (com) print some_variable (com) end (Pdb) 

对于Python 3

你可以使用pdb的显示function

一旦你打断点就input

ipdb> 显示 expression式

例:

 ipdb> display instance display instance: <AppUser: dmitry4> ipdb> display instance.id display instance.id: 9 ipdb> display instance.university display instance.university: <University: @domain.com> ipdb> display Currently displaying: instance.university: <University: @domain.com> instance.id: 9 instance: <AppUser: dmitry4> ipdb> 

正如您所看到的,每次键入display时,都会打印您的所有手表(expression式)。 您可以使用不显示function删除某些手表。

您也可以使用ppexpression式来打印expression式(非常有用)

一个可能的解决scheme是使用pdb ++ :

 pip install pdbpp 

然后用decorator @pdb.break_on_setattr “标记”你要观看的对象:

 from pdb import break_on_setattr @break_on_setattr('bar') class Foo(object): pass f = Foo() f.bar = 42 # the program breaks here 

这里pdb将会在任何Foo对象的属性bar上发生任何改变。

注意事项
只有底层__setattr__方法的调用才会触发断点。 这意味着f.bar = 'XYZ'setattr(f, 'XYZ')将起作用,但是操作bar object不会触发断点:

 f.bar = [] f.bar.append(7) # will NOT trigger breakpoint f.bar = 2 f.bar += 5 # will trigger breakpoint 

注意: @break_on_setattr不是标准的pdb -module的一部分。 pdbpdbpp覆盖/猴子修补。