你如何看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"])
这增加了两个命令, nextwatch
和stepwatch
,每个命令都将variables名称varname作为参数。 如果可能的话,他们将为varname创build当前帧的局部variables的浅拷贝,并分别继续执行next
或step
直到名称指向哪个变化。
这在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的一部分。 pdb
被pdbpp
覆盖/猴子修补。