我正在尝试让 multiprocess.apply_async
接受*args
和**kwargs
。文档指出,通过调用顺序可以做到这一点:
apply_async(func[, args[, kwds[, callback]]])
但是我不知道如何使调用语法正确。用最小的例子:
from multiprocessing import Pool
def f(x, *args, **kwargs):
print x, args, kwargs
args, kw = (), {}
print "# Normal call"
f(0, *args, **kw)
print "# Multicall"
P = Pool()
sol = [P.apply_async(f, (x,), *args, **kw) for x in range(2)]
P.close()
P.join()
for s in sol: s.get()
这按预期方式工作,提供输出
# Normal call
0 () {}
# Multicall
0 () {}
1 () {}
当args不是空元组时,例如
args = (1,2,3)
,单个调用有效,但是多处理解决方案给出:# Normal call
0 (1, 2, 3) {}
# Multicall
Traceback (most recent call last):
File "kw.py", line 16, in <module>
sol = [P.apply_async(f, (x,), *args, **kw) for x in range(2)]
TypeError: apply_async() takes at most 5 arguments (6 given)
使用kwargs参数,例如
kw = {'cat':'dog'}
# Normal call
0 () {'cat': 'dog'}
# Multicall
Traceback (most recent call last):
File "kw.py", line 15, in <module>
sol = [P.apply_async(f, (x,), *args, **kw) for x in range(2)]
TypeError: apply_async() got an unexpected keyword argument 'cat'
如何正确包装
multiprocess.apply_async
? 最佳答案
您不必显式使用*
和**
。只需传递元组和字典,然后让apply_async
将它们解包即可:
from multiprocessing import Pool
def f(x, *args, **kwargs):
print x, args, kwargs
args, kw = (1,2,3), {'cat': 'dog'}
print "# Normal call"
f(0, *args, **kw)
print "# Multicall"
P = Pool()
sol = [P.apply_async(f, (x,) + args, kw) for x in range(2)]
P.close()
P.join()
for s in sol: s.get()
输出:
# Normal call
0 (1, 2, 3) {'cat': 'dog'}
# Multicall
0 (1, 2, 3) {'cat': 'dog'}
1 (1, 2, 3) {'cat': 'dog'}
请记住,在python的文档中,如果函数接受
*args
和**kwargs
,则其签名明确声明:the_function(a,b,c,d, *args, **kwargs)
在您的情况下:
apply_async(func[, args[, kwds[, callback]]])
那里没有
*
,因此args
是的一个参数,在调用func
时将其解压缩,而kwargs
是的一个参数,并以相同的方式进行处理。另请注意,**kwargs
之后不可能有其他参数:>>> def test(**kwargs, something=True): pass
File "<stdin>", line 1
def test(**kwargs, something=True): pass
^
SyntaxError: invalid syntax
关于python - multiprocess.apply_async如何包装* args和** kwargs?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16224600/