我想通过Pool.map()将关键字参数传递给我的worker-function。在搜索论坛时,我无法找到明确的例子。
示例代码:
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()
输出:
kwarg_test = True
Success
kwarg_test = False
kwarg_test = False
kwarg_test = False
kwarg_test = False
TypeError: unsupported operand type(s) for //: 'int' and 'dict'
类型错误与解析multiprocessing.Pool或Queue中的参数有关,我尝试了其他几种语法,比如制作一个kwargs列表; [kwargs,kwargs,kwargs,kwargs],以及几次尝试将kwarg列入工作列表但没有运气。我将multiprocessing.pool中的代码从map映射到map_async并得到了
task_batches = Pool._get_tasks(func, iterable, chunksize)
在我遇到生成器结构时在pool.py中。我很高兴将来能够更多地了解这一点,但现在我只想找出答案:
是否有一个简单的语法允许使用pool.map传递kwargs?
答案 0 :(得分:14)
如果你想迭代其他参数,请使用@ArcturusB的答案。
如果您只想传递它们,每次迭代具有相同的值,那么您可以这样做:
from functools import partial
pool.map(partial(worker, **kwargs), jobs)
答案 1 :(得分:10)
multiprocessing.pool.Pool.map
doc州:
map()内置函数的并行等价物(它仅支持一个可迭代的参数)。它会阻塞,直到结果准备就绪。
我们只能传递一个可迭代的参数。故事的结局。但我们可以想到一个解决方法:定义worker_wrapper
函数,它接受一个参数,将其解包为args和kwargs,并将它们传递给worker
:
def worker_wrapper(arg):
args, kwargs = arg
return worker(*args, **kwargs)
在wrapper_process
中,您需要构建此单个参数
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
答案 2 :(得分:1)
您无需强迫自己使用 map。只需使用 apply_async 并将您的参数作为字典传递。在此示例中,batch_parameters
是包含要测试的参数的字典列表。 future_parameters
保留期货元组列表以及用于获取这些期货的参数。在接下来的循环中,我们等待期货获得它们的结果并将结果与用于生成它们的参数一起打印出来。
with Pool(parallelism) as pool:
future_parameters = [(pool.apply_async(f, kwds=parameters), parameters) for parameters in batch_parameters]
for future, parameters in future_parameters:
result = future.get()
print(parameters, "=>", result)