Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to export a variable from PDB?

Tags:

python

pdb

Imagine the following scenario: a script is started from the IPython shell and at a break point the python debugger is called. Using the PDB commands one can analyze the code and variables at this point. But often it turns out that the values of the variables call for a deeper research.

Is it possible to export the value of a variable to the IPython shell?

My specific use case: I struggle with a quite huge numpy array which does not seem to have the correct values. I know that I can run any python commands from the python debugger, but it would be helpful to save the values of the variable at different break points and to use all of them at IPython shell. I am imaging something like

ipdb> global var1; var1 = var
ipdb> continue
...
ipdb> global var2; var2 = var
ipdb> continue
... 
In [2]: abs(var1 - var2) # do some interesting calculations with IPython
like image 400
lumbric Avatar asked Feb 13 '13 17:02

lumbric


2 Answers

You need to distinguish different globals().
For example, suppose we have a module: mymodule.py

foo = 100
def test():
    bar = 200
    return bar

We run it under the control of pdb.

>>> import pdb
>>> import mymodule
>>> foobar = 300
>>> pdb.run('mymodule.test()')
> <string>(1)<module>()
(Pdb) print foobar
300
(Pdb) print foo
*** NameError: name 'foo' is not defined
(Pdb) global foobar2; foobar2 = 301
(Pdb) print foobar2
301

At the beginning, namely, before executing test(), the environment in pdb is your current globals(). Thus foobar is defined, while foo is not defined.
Then we execute test() and stop at the end of bar = 200

-> bar = 200
(Pdb) print bar
200
(Pdb) print foo
100
(Pdb) print foobar
*** NameError: name 'foobar' is not defined
(Pdb) global foo2; foo2 = 101
(Pdb) print foo2
101
(Pdb) c
>>> 

The environment in pdb has been changed. It uses mymodule's globals() in test(). Thus 'foobaris not defined. whilefoo` is defined.

We have exported two variables foobar2 and foo2. But they live in different scopes.

>>> foobar2
301
>>> mymodule.foobar2

Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    mymodule.foobar2
AttributeError: 'module' object has no attribute 'foobar2'
>>> mymodule.foo2
101
>>> foo2

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    foo2
NameError: name 'foo2' is not defined

You have already found the solution. But it works slightly differently.

like image 86
nymk Avatar answered Oct 25 '22 22:10

nymk


Not a pretty solution, but working:

ipdb> import cPickle; f=open('/tmp/dump1','w+'); cPickle.dump(var,f); f.close()

...

ipdb> import cPickle; f=open('/tmp/dump2','w+'); cPickle.dump(var,f); f.close()

then

In [2]: var1 = cPickle.load(open('/tmp/dump1'))
In [3]: var2 = cPickle.load(open('/tmp/dump2'))
like image 38
sega_sai Avatar answered Oct 25 '22 20:10

sega_sai