我正在尝试将多处理与pool.map
一起使用来加速函数的执行,但可迭代对象不是该函数的第一个参数。 Lambda 不起作用,因为它们不可腌制。 我尝试使用functools.partial
创建一个新功能,但它失败并出现TypeError
. 下面是一个非常简单的示例,具有相同的结果。 如果我将参数顺序切换为 f(i, s1, s2)
,它会按预期工作。
为什么参数顺序在这里很重要? 当我阅读文档时,这对我来说并不明显。
我有哪些选择(除了明显的更改原始功能)?
import multiprocessing
from functools import partial
def f(s1, s2, i):
return [s1] + [s2]*i
def main():
# other code... constants for f aren't known until runtime
pool = multiprocessing.Pool()
func = partial(f, s1='a', s2='c')
for strings in pool.map(func, range(10)):
print(strings)
pool.close()
pool.join()
if __name__ == '__main__':
main()
更新:我能想到的最好的是在模块级别创建一个包装器来切换参数顺序,然后从包装器中创建一个部分。 看起来一点也不漂亮,看起来一点也不蟒蛇。
import multiprocessing
from functools import partial
def f(s1, s2, i):
return [s1] + [s2]*i
def wrapper(i, s1, s2):
return f(s1, s2, i)
def main():
# other code... constants for f aren't known until runtime
pool = multiprocessing.Pool()
func = partial(wrapper, s1='foo', s2='bar')
for strings in pool.map(func, range(10)):
print(strings)
pool.close()
pool.join()
if __name__ == '__main__':
main()
顺序很重要,因为pool.map
正在调用f(i, s1='a', s2='c')
。你可以这样写你的部分:
import multiprocessing
def f(s1, s2, i):
return [s1] + [s2]*i
def f2(i):
return f('a','c',i)
if __name__ == '__main__':
pool = multiprocessing.Pool()
for strings in pool.map(f2, range(10)):
print(strings)
pool.close()
pool.join()
如果您使用的是 python3.3,您可以使用pool.starmap
:
import multiprocessing
from itertools import repeat
def f(s1, s2, i):
return [s1] + [s2]*i
if __name__ == '__main__':
pool = multiprocessing.Pool()
for strings in pool.starmap(f, zip(repeat('a'), repeat('c'), range(10))):
print(strings)
pool.close()
pool.join()