我有一个主进程,它使用execfile并在子进程中运行脚本。
,除非脚本在另一个目录中,否则这样可以正常工作这是mainprocess.py
:
from multiprocessing import Process
m = "subdir\\test.py"
if __name__ == '__main__':
p = Process(target = execfile, args = (m,))
p.start()
然后在一个名为subdir的子目录中,我有test.py
import time
def foo():
print time.time()
foo()
当我运行mainprocess.py
时,我收到错误:
NameError: global name 'time' is not defined
但问题不仅限于模块名称 - 有时我会在其他代码段上的函数名称上出错。
我已尝试在mainprocess.py
中导入时间,也在if
语句中导入时间,但都没有任何效果。
避免错误的一种方法(我没试过这个)是将test.py
复制到父目录中,并在文件中插入一行到os.chdir
回到原始目录。但是,这似乎相当草率。
那发生了什么?
答案 0 :(得分:1)
解决方案是更改您的流程初始化:
p = Process(target=execfile, args=(m, {}))
老实说,我不完全确定为什么会这样。我知道它与添加时间导入的字典(本地人与全局)有关。看起来当你在test.py中导入时,它被视为局部变量,因为以下工作:
import time # no foo() anymore
print(time.time()) # the call to time.time() is in the same scope as the import
但是,以下内容也有效:
import time
def foo():
global time
print(time.time())
foo()
第二个例子告诉我,导入仍然分配给某种类型的全局命名空间,我只是不知道如何或为什么。
如果正常调用execfile(),而不是在子进程中,一切运行正常,事实上,你可以在主进程调用execfile()之后的任何地方使用time模块,因为时间已经过了带入相同的命名空间。我认为,由于您在子进程中启动它,因此没有用于分配导入的模块级命名空间(execfile在调用时不会创建模块对象)。我认为当我们将空字典添加到对execfile的调用时,我们正在添加提供全局字典参数,从而为导入机制提供了一个全局命名空间来指定名称时间 to。
背景的一些链接:
1)Tutorial page on namespaces and scope - 首先查看内置,全局和本地名称空间解释