如何让调用者的命名空间可用于导入函数中的IPython?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (151)

我试图调用'timex.py'中定义的小辅助函数,该函数从'caller.py'调用,而后者应该通过“%run caller.py”从(PyCharm的)IPython-console调用。

这当前导致“NameError:name'pickle'未定义”。

# 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

显然,ipython timeit-magic的命名空间不包含caller.py-globals。传递globals()作为time_expression的参数并从time_expression中更新全局变量没有帮助,并且传递get_ipython()作为参数没有做到这一点。

有没有办法让它发挥作用?

如果我caller.py使用“ipython caller.py”在Terminal中定义time_expression 并调用它,它会工作,但我更喜欢将它放在库中,然后将其导入到需要的地方。

(Python 3.6.3,IPython 6.2.1)

提问于
用户回答回答于

我发现shell有一个'user_ns'参数。然后使用调用者的本地更新此user_ns-dictionary是通过从IPython控制台运行%run caller.py来使其从caller.py导入的解决方案。

也许有更好的方式?

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}")

扫码关注云+社区

领取腾讯云代金券