9

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ますか?

4

1 に答える 1

22

*and を**明示的に使用する必要はありません。タプルと dict を渡すだけで、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'}

関数が受け入れ*args**kwargsその署名が明示的に次のように述べている場合、Pythonのドキュメントで覚えておいてください。

the_function(a,b,c,d, *args, **kwargs)

あなたの場合:

apply_async(func[, args[, kwds[, callback]]])

存在*しないため、呼び出し時に展開され、1の引数でargsあり、同じ方法で処理される1つの引数です。また、 の後に他の引数を指定することはできないことに注意してください:funckwargs**kwargs

>>> def test(**kwargs, something=True): pass

  File "<stdin>", line 1
    def test(**kwargs, something=True): pass
                     ^
SyntaxError: invalid syntax
于 2013-04-25T21:02:01.517 に答える