python - 如何使调用者的命名空间可用于导入函数中的 IPython 魔法?

标签 python function namespaces ipython ipython-magic

我正在尝试调用在 'timex.py' 中定义的一个小辅助函数,它是从 'caller.py' 调用的,而后者又应该通过“%run caller.py”从(PyCharm 的)IPython 控制台调用。

这当前导致“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)

最佳答案

好吧,看来我很幸运。
我在这里找到了一个提示 link ,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}")

关于python - 如何使调用者的命名空间可用于导入函数中的 IPython 魔法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47851265/

相关文章:

python - python 3.6 subprocess.Popen().returncode of 100 是什么意思?

python - 输出列表中的所有负数

python - Caffe GoogleNet 模型预测始终相同

python - 本地主机网络应用程序。获取浏览器中文件的完整路径

python - numpy.heaviside 和机器精度

python - 如何在 Azure Functions API (Python) 中处理 CORS 预检?

c++ - 排序函数 C++

jquery通过分配给单个元素的命名空间解除绑定(bind)多个事件

php - 在 PHP 中组织/使用可重用的代码库

python - 如果我使用与父类(super class)相同的名称,我是否会覆盖子类方法中的父类(super class)定义?