Man*_*anu 5 python yield generator multiprocessing
有人可以解释下面的代码有什么问题吗
from multiprocessing import Pool
def sq(x):
yield x**2
p = Pool(2)
n = p.map(sq, range(10))
Run Code Online (Sandbox Code Playgroud)
我收到以下错误
MaybeEncodingError Traceback (最近一次调用最后一次) in () 5 p = Pool(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 get(self, timeout) 606 return self._value 607 else: --> 608 raise self._value 609 610 def _set(self, i,目标):
MaybeEncodingError: 错误发送结果:'[, ]'。原因:'TypeError(“不能腌制生成器对象”,)'
提前谢谢了。
您必须在这里使用函数而不是生成器。意思是:改变yield
byreturn
转换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__':
Run Code Online (Sandbox Code Playgroud)
从字面上引用我得到的评论,因为它是不言自明的:
Windows 上的错误是因为每个进程都会生成一个新的 python 进程,该进程解释 python 文件等,因此“if main 块”之外的所有内容都会再次执行”
因此为了便于移植,您必须__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)
Run Code Online (Sandbox Code Playgroud)
结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Run Code Online (Sandbox Code Playgroud)
编辑:如果您不想预先存储值,您可以使用imap
:
n = p.imap(sq, range(10))
Run Code Online (Sandbox Code Playgroud)
n
现在是一个生成器对象。为了使用这些值(并激活实际处理),我强制迭代列表,并得到与上面相同的结果:
print(list(n))
Run Code Online (Sandbox Code Playgroud)
请注意,文档表明它imap
比map
.