我正在尝试调用一个在'timex.py‘中定义的小辅助函数,它是从'caller.py’调用的,而这个函数应该通过"%run caller.py“从(PyCharm的) IPython-console调用。
这当前导致"NameError:名称'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中更新globals没有帮助,作为参数传递get_ipython()也无济于事。
有没有办法让它工作呢?
如果我在caller.py
中定义time_expression,并使用"ipython caller.py“从终端调用它,那么它就可以工作,但我更喜欢将它放在一个库中,然后将它导入到需要的地方。
(Python 3.6.3,IPython 6.2.1)
发布于 2017-12-17 12:14:59
好的,看起来我很幸运。我在这里发现了一个提示,link有一个'user_ns‘参数。通过从IPython控制台运行%run caller.py,然后使用调用者的本地变量更新此user_ns字典,可以使其在从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}")
https://stackoverflow.com/questions/47851265
复制相似问题