2015-12-01 5 views
8

私は、Pool.map()でワーカー関数にキーワード引数を渡したいと思います。私はフォーラムを検索するときにこれの明確な例を見つけることができません。multiprocessing.pool.mapでkwargsを渡します。

コード例:

import multiprocessing as mp 

def worker((x,y), **kwargs): 
    kwarg_test = kwargs.get('kwarg_test', False) 
    print("kwarg_test = {}".format(kwarg_test))  
    if kwarg_test: 
     print("Success") 
    return x*y 

def wrapper_process(**kwargs): 
    jobs = [] 
    pool=mp.Pool(4) 
    for i, n in enumerate(range(4)): 
     jobs.append((n,i)) 
    pool.map(worker, jobs) #works 
    pool.map(worker, jobs, kwargs) #how to do this? 

def main(**kwargs): 
    worker((1,2),kwarg_test=True) #accepts kwargs 
    wrapper_process(kwarg_test=True) 

if __name__ == "__main__":  
    main() 

出力:

​​

型エラーがmultiprocessing.Poolまたはキューの内部で解析引数に関係している、と私は作るような、いくつかの他の構文を試してみましたkwargsのリスト。 [kwargs、kwargs、kwargs、kwargs]だけでなく、ジョブリストにkwargを含めるいくつかの試みが運がない。私はmapからmap_asyncへのmultiprocessing.poolのコードをトレースし、ジェネレータ構造に遭遇したときに task_batches = Pool._get_tasks(func, iterable, chunksize) までpool.pyに到達しました。私は将来これについてもっと学ぶことができてうれしいですが、今のところ私はただ見つけようとしています:

kwargsとpool.mapの受け渡しを許可する簡単な構文はありますか?

答えて

6

multiprocessing.pool.Pool.map doc状態:

マップ()組み込み関数(しかし一つだけ反復可能な引数をサポートしている)の並列等価。結果が準備完了するまでブロックされます。

反復可能な引数は1つしか渡すことができません。ストーリーの終わり。しかし、我々はluckilly回避策を考えることができます:

はあなたの wrapper_process
def worker_wrapper(arg): 
    args, kwargs = arg 
    return worker(*args, **kwargs) 

、あなたがから、この単一の引数を構築する必要があります。引数とkwargsからにそれを解凍し、単一の引数を取り、workerに渡すworker_wrapper関数を定義します jobs(あるいは直接雇用を構築するとき)とworker_wrapperを呼び出します。ここでは

arg = [(j, kwargs) for j in jobs] 
pool.map(worker_wrapper, arg) 

は作業の実装では、あなたの元 コードのできるだけ近くに保た:

テストに合格
import multiprocessing as mp 

def worker_wrapper(arg): 
    args, kwargs = arg 
    return worker(*args, **kwargs) 

def worker(x, y, **kwargs): 
    kwarg_test = kwargs.get('kwarg_test', False) 
    # print("kwarg_test = {}".format(kwarg_test))  
    if kwarg_test: 
     print("Success") 
    else: 
     print("Fail") 
    return x*y 

def wrapper_process(**kwargs): 
    jobs = [] 
    pool=mp.Pool(4) 
    for i, n in enumerate(range(4)): 
     jobs.append((n,i)) 
    arg = [(j, kwargs) for j in jobs] 
    pool.map(worker_wrapper, arg) 

def main(**kwargs): 
    print("=> calling `worker`") 
    worker(1, 2,kwarg_test=True) #accepts kwargs 
    print("=> no kwargs") 
    wrapper_process() # no kwargs 
    print("=> with `kwar_test=True`") 
    wrapper_process(kwarg_test=True) 

if __name__ == "__main__":  
    main() 

:あなたが他の引数を反復処理したい場合は

=> calling `worker` 
Success 
=> no kwargs 
Fail 
Fail 
Fail 
Fail 
=> with `kwar_test=True` 
Success 
Success 
Success 
Success 
8

、ArcturusBの答え@使用しています。あなただけの反復ごとに同じ値を持つ、それらを渡したい場合は

、あなたはこれを行うことができます。

​​

Partial「バインド」引数を関数に。古いバージョンのPython cannotは部分的なオブジェクトをシリアライズします。

関連する問題