【问题标题】:How to make caller's namespace available to IPython's magic inside imported function?如何使调用者的命名空间可用于导入函数中的 IPython 魔术?
【发布时间】:2018-05-30 18:44:19
【问题描述】:

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

目前这会导致“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

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

有没有办法让它工作?

如果我在 caller.py 中定义 time_expression 并使用“ipython caller.py”从终端调用它,它会起作用,但我更愿意将它放在一个库中,然后将它导入到需要的地方。

(Python 3.6.3,IPython 6.2.1)

【问题讨论】:

    标签: python function namespaces ipython ipython-magic


    【解决方案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}")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 2020-09-09
      • 2019-05-08
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多