多处理时全局变量的NameError,仅在子目录中

时间:2014-07-06 15:37:31

标签: python python-2.7 multiprocessing nameerror

我有一个主进程,它使用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回到原始目录。但是,这似乎相当草率。

那发生了什么?

1 个答案:

答案 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 - 首先查看内置,全局和本地名称空间解释

2)Python docs on execfile command

3)A very similar question on a non-SO site