How do you watch a variable in pdb

ε祈祈猫儿з 提交于 2019-11-27 00:05:56

问题


I'm debugging a python script, and I want to watch a variable for a change (much like you can watch a memory adress in gdb). Is there a way to do this?


回答1:


For watching a variable when you are hitting a breakpoint, you can use the commands command. E.g. printing some_variable when hitting breakpoint #1 (canonical example from pdb doc).

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

Update for Python 3

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

Additionally, you can use the condition command to ensure the breakpoint is only hit whenever the variable takes a certain value.

eg:

(Pdb) condition 1 some_variable==some_value



回答2:


Here is a really hacky way to do this with pdb. These commands can be put in your ~/.pdbrc for automatic loading every time you use 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"])

This adds two commands, nextwatch and stepwatch which each take a variable name varname as an argument. They will make a shallow copy of the current frame's local variable for varname if possible, and keep executing next or step respectively until what that name points to changes.

This works in CPython 2.7.2 but relies on some pdb internals so it will probably break elsewhere.




回答3:


For Python 3:

you can use display functionality of pdb

Once you hit the breakpoint just type

ipdb> display expression

example:

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> 

as you can see, each time you type display - it will print all of your watches (expressions). You can use builtin function undisplay to remove certain watch.

You can also use pp expression to prettyprint the expression (very useful)




回答4:


A possible solution is to use pdb++:

pip install pdbpp

Then "mark" the object you want to watch with the 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

Here pdb will break on any change of the attribute bar on any Foo-object.

Caveats
Only invocations of the underlying __setattr__-method will trigger the breakpoint. This means that f.bar = 'XYZ' and setattr(f, 'XYZ') will work, but manipulating the bar-object will not trigger the breakpoint:

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

f.bar = 2
f.bar += 5      # will trigger breakpoint

Note: @break_on_setattr is not part of the standard pdb-module. pdb is overridden/monkey-patched by the pdbpp-package.

You can also wrap an existing object (via its class) after pdb.set_trace():

(Pdb++) import pdb
(Pdb++) pdb.break_on_setattr('tree_id')(self.__class__)
(Pdb++) continue


来源:https://stackoverflow.com/questions/7668979/how-do-you-watch-a-variable-in-pdb

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!