当我在 ipython 交互式 shell 中时,我试图从脚本中动态加载函数。例如,假设我有一个这样的 python 脚本:
# script.py
import IPython as ip
def Reload():
execfile('routines.py', {}, globals())
if __name__ == "__main__":
ip.embed()
假设文件routines.py 是这样的:
# routines.py
def f():
print 'help me please.'
def g():
f()
现在,如果我运行脚本 script.py,我将进入交互式 shell。如果我键入以下内容,我对 g() 的调用将起作用:
execfile('routines.py')
g()
但是,如果我键入以下内容,对 g() 的调用将失败:
Reload()
g()
我将收到一条错误消息,提示“未定义全局名称 f”。,尽管当我在交互式 shell 中键入 globals() 时,我仍然可以看到 f 和 g 在输出中。
这两者有什么区别?
更新:
以下工作,但它不是首选解决方案,所以我想为上述问题提供更好的解决方案。
如果我将 script.py 更改为:
# script.py
import IPython as ip
def Reload():
execfile('routines.py')
if __name__ == "__main__":
ip.embed()
并将routines.py更改为:
# routines.py
global f
global g
def f():
print 'help me please.'
def g():
f()
然后,如果我在交互式 shell 中调用 Reload(),然后调用 g(),它就可以工作。但是,这不是首选方法,因为我必须声明全局名称。
更新 2:
似乎问题与ipython无关。如果我启动 python shell,使用第一个版本的routines.py,然后手动输入以下内容:
def Reload():
execfile('routines.py', {}, globals())
g()
对 g() 的调用也失败了。但以下工作:
execfile('routines.py')
g()