Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dump function variables to workspace in python/ipython

Tags:

python

ipython

When developing and debugging with python/ipython repl, at some point I'd like to dump all the local variables in a function to the workspace to see what's going on. Suppose I have a function

def func():
    a = "blablabla"
    b = 1234
    c = some_calculation_of_a_and_b(a,b)
    dump_to_workspace(a,b,c)   # is this possible?,  or even more preferable:
    dump_all_local_variables_to_workspace()   # is this possible?

I hope to be able to run this in python/ipython:

>>> func()
>>> print a
"blablabla"
>>> print b
1234
>>> print c
some_calculated_value

I know two alternatives: (1) return the variables from the function [not good because I don't want to mess up with return value], and (2) save the data to a file on the disk [not convenient because it involve disk I/O with possibly large amount of data]. But those aren't as convenient most of the times. Is there a way to achieve the dumping directly?

Thanks a lot in advance!

like image 986
Ying Xiong Avatar asked Nov 09 '14 16:11

Ying Xiong


1 Answers

This is a hugly hack, but I use it very often in my jupyter notebooks for dumping some local state to the global workspace for further inspection. Simply add these two lines to the end of your function and then you'll have access to all the local variables directly from the notebook:

import inspect
inspect.getmodule(next(frm[0] for frm in reversed(inspect.stack())
                       if frm[0].f_locals.get('__name__', None) == '__main__')).__dict__.update(locals())

What it does is traverse the stack in reverse order (using the inspect module) to find the top-most module named '__main__'. That's the module representing the notebook (i.e. the current kernel). It then updates the module's global variables definition using __dict__ with the function's locals (using __locals__)

Here's a demo in a notebook: https://colab.research.google.com/drive/1lQgtmqigCUmzVhkX7H7azDWvT3CfxBtt

#%%
def some_calculation_of_a_and_b(a, b):
    return 'some_calculated_value'

def func():
    a = "blablabla"
    b = 1234
    c = some_calculation_of_a_and_b(a,b)

    #dump_all_local_variables_to_workspace():
    import inspect
    inspect.getmodule(next(frm[0] for frm in reversed(inspect.stack())
                      if frm[0].f_locals.get('__name__', None) == '__main__')).__dict__.update(locals())

#%%
func()
print(a)
print(b)
print(c)

# this will print:
# blablabla
# 1234
# some_calculated_value
like image 127
stav Avatar answered Sep 29 '22 00:09

stav