给出AttributeError

时间:2016-12-29 18:59:38

标签: python multithreading

我正在尝试在我的代码中实现多处理,所以,我想我会从一些例子开始学习。我使用了documentation中的第一个示例。

from multiprocessing import Pool
def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))

当我运行上面的代码时,我得到一个AttributeError: can't get attribute 'f' on <module '__main__' (built-in)>。我不知道为什么我会收到这个错误。如果有帮助,我也使用Python 3.5。

3 个答案:

答案 0 :(得分:21)

这个问题似乎是多处理的一个设计特征.Pool。见https://bugs.python.org/issue25053。由于某种原因,Pool并不总是使用未在导入模块中定义的对象。因此,您必须将您的函数写入不同的文件并导入模块。

文件: defs.py

def f(x):
    return x*x

文件: run.py

from multiprocessing import Pool
import defs

 if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(defs.f, [1, 2, 3]))

如果使用print或其他内置函数,则该示例应该有效。如果这不是一个错误(根据链接),则会严重选择给定的示例。

答案 1 :(得分:3)

在使用IPython时,multiprocessing模块有一个主要限制:

此软件包中的功能需要__main__模块为 由儿童进口。 [...]这意味着一些例子,例如 因为multiprocessing.pool.Pool示例在 交互式口译员。 [from the documentation]

幸运的是,有一个multiprocessing模块的分支,称为multiprocess,该模块使用莳萝而不是pickle进行序列化,从而方便地克服了这个问题。

只需在您的导入中安装multiprocess并将multiprocessing替换为multiprocess

import multiprocess as mp

def f(x):
    return x*x

with mp.Pool(5) as pool:
    print(pool.map(f, [1, 2, 3, 4, 5]))

当然,按照this answer中的建议对代码进行外部化也可以,但是我发现它非常不便:这不是为什么(以及如何)使用IPython环境。

multiprocessing不能立即在IPython环境中工作,请改用其分叉multiprocess

答案 2 :(得分:0)

如果您正在使用Jupyter笔记本电脑(如OP),则在单独的单元格中定义函数并执行该单元格首先可以解决该问题。可接受的答案也可以,但是更多的工作。之前(即池上方)定义功能是不够的。它必须位于首先执行的完全不同的笔记本单元中。