给出 AttributeError 的多处理示例

新手上路,请多包涵

我正在尝试在我的代码中实现多处理,因此,我认为我应该从一些示例开始学习。我使用了本 文档 中的第一个示例。

 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。

原文由 PiccolMan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 814
2 个回答

这个问题似乎是 multiprocessing.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 或其他内置函数,该示例应该有效。如果这不是错误(根据链接),则给定的示例选择不当。

原文由 hr87 发布,翻译遵循 CC BY-SA 3.0 许可协议

multiprocessing 模块在 IPython 使用方面有一个主要限制:

此包中的功能要求 __main__ 模块可由子项导入。 […] 这意味着一些示例,例如 multiprocessing.pool.Pool 示例将无法在交互式解释器中工作。 [ 来自文档]

幸运的是,有一个名为 --- multiprocessing 模块的分支 multiprocess 使用 dill 而不是 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]))

当然,按照 此答案 中的建议将代码外部化也可以,但我发现它非常不方便:这不是我使用 IPython 环境的原因(以及方式)。

multiprocessing 不能立即在 IPython 环境中工作,请使用其分支 multiprocess 代替。

原文由 Michael Dorner 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题