我正在尝试使用pool.map
的多处理来加速函数的执行,但是iterable不是该函数的第一个参数。 Lambdas不会起作用,因为它们不是可选择的。我尝试使用functools.partial
创建一个新函数,但它失败了TypeError
。下面是一个非常简单的例子,结果相同。如果我将参数顺序切换为f(i, s1, s2)
,它将按预期工作。
为什么参数顺序在这里很重要?当我阅读doc时,对我来说并不明显。
我有哪些选择(除了改变原始功能之外)?
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()
更新: 我能想到的最好的方法是在模块级别创建一个包装器来切换参数顺序,然后在包装器中创建一个部分包装器。看起来不漂亮或看似pythonic。
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()
答案 0 :(得分:1)
由于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()