如何在 Python 多处理中指定某个关键字参数
How to specify a certain keyword argument in Python multiprocessing
对于有很多参数的函数,包括位置和关键字参数。如何在不重复先前关键字参数的情况下为关键字参数指定列表?
例如
import multiprocessing
from functools import partial
def foo(a, b, c=1, d=2, e=3):
print(multiprocessing.current_process().name)
print(a + b + c + d + e)
return a + b + c + d + e
with multiprocessing.Pool(processes=2) as pool:
# I would like to give [1,2,3,4] to "e", something like
# dic = {'e': [1,2,3,4]}
# Yet we still have c = 1, d = 2.
results = pool.map(partial(foo, 2, 3), dic)
参数列表可能很长,我不想在每个部分函数中键入“c=1,d=2”。
我知道可以使用 multiprocessing.apply
,但我希望与此函数的其他用法保持一致,并且只使用 map
。
我认为您将需要某种包装函数,因为它似乎用 partial
can't be done 填充关键字参数。在最一般的情况下,你可以有一个调用函数,它接受一个 (function, args, kwargs) 的元组——并传递给 pool.map
这个通用调用者和一个这样的 3 元素元组列表:
import multiprocessing
from functools import partial
def foo(a, b, c=1, d=2, e=3):
print(multiprocessing.current_process().name)
print(a, b, c, d, e, a + b + c + d + e)
return a + b + c + d + e
def generic_caller(tup):
func, args, kwargs = tup
return func(*args, **kwargs)
with multiprocessing.Pool(processes=2) as pool:
tups = [(foo, [2, 3], {'e': val})
for val in [1, 2, 3, 4]]
results = pool.map(generic_caller, tups)
print(results)
这给出了以下内容(请注意,我将各个变量添加到 foo
内的 print
语句中):
ForkPoolWorker-2
2 3 1 2 1 9
ForkPoolWorker-2
2 3 1 2 2 10
ForkPoolWorker-2
2 3 1 2 4 12
ForkPoolWorker-1
2 3 1 2 3 11
[9, 10, 11, 12]
或者您可能更喜欢包装器中的 hard-code func
and/or args
,并从传递的元组中省略任何 hard-coded 项.
不幸的是,涉及使用闭包作为包装函数的解决方案(以避免每次都必须传递相同的 a
和 b
值)运行 进入问题,这不是可腌制,因此可以与 map
一起使用,但不能与 pool.map
.
一起使用
对于有很多参数的函数,包括位置和关键字参数。如何在不重复先前关键字参数的情况下为关键字参数指定列表?
例如
import multiprocessing
from functools import partial
def foo(a, b, c=1, d=2, e=3):
print(multiprocessing.current_process().name)
print(a + b + c + d + e)
return a + b + c + d + e
with multiprocessing.Pool(processes=2) as pool:
# I would like to give [1,2,3,4] to "e", something like
# dic = {'e': [1,2,3,4]}
# Yet we still have c = 1, d = 2.
results = pool.map(partial(foo, 2, 3), dic)
参数列表可能很长,我不想在每个部分函数中键入“c=1,d=2”。
我知道可以使用 multiprocessing.apply
,但我希望与此函数的其他用法保持一致,并且只使用 map
。
我认为您将需要某种包装函数,因为它似乎用 partial
can't be done 填充关键字参数。在最一般的情况下,你可以有一个调用函数,它接受一个 (function, args, kwargs) 的元组——并传递给 pool.map
这个通用调用者和一个这样的 3 元素元组列表:
import multiprocessing
from functools import partial
def foo(a, b, c=1, d=2, e=3):
print(multiprocessing.current_process().name)
print(a, b, c, d, e, a + b + c + d + e)
return a + b + c + d + e
def generic_caller(tup):
func, args, kwargs = tup
return func(*args, **kwargs)
with multiprocessing.Pool(processes=2) as pool:
tups = [(foo, [2, 3], {'e': val})
for val in [1, 2, 3, 4]]
results = pool.map(generic_caller, tups)
print(results)
这给出了以下内容(请注意,我将各个变量添加到 foo
内的 print
语句中):
ForkPoolWorker-2
2 3 1 2 1 9
ForkPoolWorker-2
2 3 1 2 2 10
ForkPoolWorker-2
2 3 1 2 4 12
ForkPoolWorker-1
2 3 1 2 3 11
[9, 10, 11, 12]
或者您可能更喜欢包装器中的 hard-code func
and/or args
,并从传递的元组中省略任何 hard-coded 项.
不幸的是,涉及使用闭包作为包装函数的解决方案(以避免每次都必须传递相同的 a
和 b
值)运行 进入问题,这不是可腌制,因此可以与 map
一起使用,但不能与 pool.map
.