views:

79

answers:

2

I am using pdb to examine a script having called run -d in an ipython session. It would be useful to be able to plot some of the variables but I need them in the main ipython environment in order to do that.

So what I am looking for is some way to make a variable available back in the main interactive session after I quit pdb. If you set a variable in the topmost frame it does seem to be there in the ipython session, but this doesn't work for any frames further down.

Something like export in the following:

ipdb> myvar = [1,2,3]
ipdb> p myvar
[1, 2, 3]
ipdb> export myvar
ipdb> q

In [66]: myvar
Out[66]: [1, 2, 3]
+1  A: 

Per ipython's docs, and also a run? command from the ipython prompt,

after execution, the IPython interactive namespace gets updated with all variables defined in the program (except for __name__ and sys.argv)

By "defined in the program" (a slightly sloppy use of terms), it doesn't mean "anywhere within any nested functions found there" -- it means "in the globals() of the script/module you're running. If you're within any kind of nesting, globals()['myvar'] = [1,2,3] should still work fine, just like your hoped-for export would if it existed.

Edit: If you're in a different module, you need to set the name in the globals of your original one -- after an import sys if needed, sys.modules["originalmodule"].myvar = [1, 2, 3] will do what you desire.

Alex Martelli
I had tried making the variable a global but this doesn't seem to work if another module has been called in one of the frames. For example if you run test.py which calls a function in test2.py and then declare a global in this frame I can't see it in either the higher up frames (executing in another module) or the ipython namespace afterwards.
ihuston
If you're in a different module, you need to set the name in the globals of your original one -- editing my answer accordingly.
Alex Martelli
Turns out that making a variable global in a frame inside a module called from the original script puts it only in the __dict__ of that module. So from the top-most frame "test2" is in globals() and "myvar" is in globals()["test2"].__dict__. I think I presumed that making the variable global would put it straight into globals() for the top frame (and ipython) but that doesn't seem to work.
ihuston
Started my last comment before yours had come up. Marking as accepted. Thanks for the help!
ihuston
A: 

What you have should work (just without the "export" line).

ipdb> myvar = [1,2,3]
ipdb> q

In [5]: myvar
Out[5]: [1, 2, 3]
tom10