简体   繁体   中英

How to make caller's namespace available to IPython's magic inside imported function?

I'm trying to call a small helper-function defined in 'timex.py' which is called from 'caller.py', which in turn should get called from (PyCharm's) IPython-console through "%run caller.py".

This currently results in "NameError: name 'pickle' is not defined".

# timex.py

from IPython import get_ipython

def time_expression(exp: str):    
    print(f"time expression: {exp}", flush=True)
    return get_ipython().magic(f"timeit {exp}")

# caller.py

import pickle
from timex import time_expression

packet = [*range(10**2)]
time_expression("pickle.dumps(packet, protocol=-1)")

# Then run from IPython-console:

>>>%run caller.py
time expression: pickle.dumps(packet, protocol=-1)
NameError: name 'pickle' is not defined

Obviously the namespace of the ipython timeit-magic doesn't contain caller.py-globals. Passing globals() as argument of time_expression and updating globals from within time_expression didn't help, as well as passing get_ipython() as argument did not do the trick.

Is there a way to make it work?

It works if I define time_expression in caller.py and called from Terminal with "ipython caller.py", but I'd prefer to put it in a library and just import it into where needed.

(Python 3.6.3, IPython 6.2.1)

Ok it seems I had luck. I found a hint here link , that there is an 'user_ns' argument for the shell. Updating this user_ns-dictionary then with the caller's locals was the solution to make it work on imports from caller.py through running %run caller.py from the IPython console.

It's a bit hacky and I feel dirty now ;) Maybe there's a more elegant way?

import sys
from IPython import get_ipython

def time_expression(exp: str):
    """"""
    ipy = get_ipython()
    ipy.__dict__['user_ns'].update(sys._getframe(1).f_locals)
    print(f"time expression: {exp}", flush=True)
    return ipy.magic(f"timeit {exp}")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM