【问题标题】:Python multiprocessing map function errorPython多处理地图功能错误
【发布时间】:2013-07-15 15:10:15
【问题描述】:

我正在尝试创建一个简单的多处理示例。普通的 map() 函数版本可以工作,但是当更改为 Pool.map 时,我收到了一个奇怪的错误:

from multiprocessing import Pool
from functools import partial
x = [1,2,3]
y = 10
f = lambda x,y: x**2+y

# ordinary map works:
map(partial(f,y=y),x)
# [11, 14, 19]

# multiprocessing map does not
p = Pool(4)
p.map(partial(f, y=y), x)
Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 504, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 319, in _handle_tasks
    put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed

酸洗错误?这究竟是什么?

【问题讨论】:

    标签: python parallel-processing functional-programming multiprocessing functools


    【解决方案1】:

    Pool.map 的参数必须是可挑选的。 Module-level functions are picklable,但 partial(f, y=y) 未在模块级别定义,因此不可选择。

    有一个简单的解决方法:

    def g(x, y=y):
        return f(x, y)
    
    p.map(g, x)
    

    使用functools.partial used to be unpickable 实现的功能。 但是,对于 Python2.7 或更高版本,您还可以使用 functools.partial 定义 g(在模块级别):

    import multiprocessing as mp
    import functools
    
    def f(x, y):
        return x**2 + y
    
    x = [1,2,3]
    y = 10
    
    g = functools.partial(f, y=y)
    
    if __name__ == '__main__':
        p = mp.Pool()
        print(p.map(g, x))
    

    产生[11, 14, 19]。但请注意,要获得此结果 f 必须使用 def 而不是 lambda 定义。我认为这是因为pickle relies on "fully qualified" name references 查找函数对象值。

    【讨论】:

    • 对不起,我不太明白——我有另一个几乎完全相同的脚本,使用部分脚本,它确实有效,而这个不。在模块级别定义的东西是什么意思?啊,看到你的更新——是的,def 与 lambda 正是有效和无效之间的区别。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 1970-01-01
    • 2020-11-22
    • 2021-02-27
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    相关资源
    最近更新 更多