使用带生成器函数的python多处理模块时出错。

时间:2017-02-04 13:34:16

标签: python multiprocessing generator yield

有人可以解释下面的代码

有什么问题
from multiprocessing import Pool
def sq(x):
    yield x**2
p = Pool(2)

n = p.map(sq, range(10))

我收到以下错误

  

MaybeEncodingError Traceback(最近一次调用   最后)in()         5 p =游泳池(2)         6   ----> 7 n = p.map(sq,range(10))

     

/home/devil/anaconda3/lib/python3.4/multiprocessing/pool.py in   map(self,func,iterable,chunksize)       返回列表中的258。       259'''    - > 260返回self._map_async(func,iterable,mapstar,chunksize).get()       261       262 def starmap(self,func,iterable,chunksize = None):

     

/home/devil/anaconda3/lib/python3.4/multiprocessing/pool.py in   得到(自我,超时)       606返回self._value       607其他:    - > 608提高self._value       609       610 def _set(self,i,obj):

     

MaybeEncodingError:发送结果时出错:' [,]'。原因:   ' TypeError("不能生成发生器对象",)'

非常感谢提前。

1 个答案:

答案 0 :(得分:4)

您必须在此处使用功能而不是生成器。表示:按yield更改return以将sq转换为函数。 Pool无法使用生成器。

此外,当尝试在Windows上创建工作版本时,我有一个奇怪的重复错误消息。

Attempt to start a new process before the current process
has finished its bootstrapping phase.

This probably means that you are on Windows and you have
forgotten to use the proper idiom in the main module:

if __name__ == '__main__':

字面引用我得到的评论,因为它不言自明:

  

Windows上的错误是因为每个进程都会生成一个新的python进程,该进程会解释python文件等,所以“if main block”之外的所有内容都会再次执行“

因此,为了便携,您必须在运行此模块时使用__name__=="__main__"

from multiprocessing import Pool

def sq(x):
    return x**2

if __name__=="__main__":
    p = Pool(2)
    n = p.map(sq, range(10))
    print(n)

结果:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

编辑:如果您不想预先存储值,可以使用imap

n = p.imap(sq, range(10))

n现在是一个生成器对象。为了使用这些值(并激活实际处理),我强制迭代列表,并得到与上面相同的结果

print(list(n))

请注意,文档指出imapmap

慢得多