如何将仅关键字参数应用于多处理池中的函数?
Posted
技术标签:
【中文标题】如何将仅关键字参数应用于多处理池中的函数?【英文标题】:How to apply keyword-only arguments to a function in a multiprocessing pool? 【发布时间】:2020-02-15 14:50:32 【问题描述】:我有一个只接受关键字参数的函数,并希望在进程池中运行它。如何将我的条目从可迭代项作为关键字参数传递给进程中的函数?
import multiprocessing
greetees = ('Foo', 'Bar')
def greet(*, greetee):
return f'Hello, greetee!'
我尝试使用 multiprocessing.map:
greetings = multiprocessing.Pool(2).map(greet, greetees)
for greeting in greetings:
print(greeting)
但这引发了一个异常,正如预期的那样:
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "/usr/lib/python3.6/multiprocessing/pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "/usr/lib/python3.6/multiprocessing/pool.py", line 44, in mapstar
return list(map(*args))
TypeError: greet() takes 0 positional arguments but 1 was given
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/bengt/Projekte/gitlab.com/PFASDR/PFASDR.Code.Main/pfasdr/neural/multi_pool_kwargs.py", line 10, in <module>
greetings = multiprocessing.Pool(2).map(greet, greetees)
File "/usr/lib/python3.6/multiprocessing/pool.py", line 266, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "/usr/lib/python3.6/multiprocessing/pool.py", line 644, in get
raise self._value
TypeError: greet() takes 0 positional arguments but 1 was given
如果我删除星号以不要求参数仅是关键字,则效果很好:
[...]
def greet(greetee):
return f'Hello, greetee!'
[...]
输出:
Hello, Foo!
Hello, Bar!
【问题讨论】:
【参考方案1】:感谢Mad Physicist 和this QnA,可以使用functools.partial 将仅关键字参数注入函数:
from functools import partial
greetings = []
for i in range(len(greetees)):
kwargs = 'greetee': greetees[i]
greet_partial = partial(greet, **kwargs)
greetings.append(multiprocessing.Pool(2).apply(greet_partial))
或具有较少可变出血:
from functools import partial
greetings = [
multiprocessing.Pool(2).apply(
partial(greet, **'greetee': greetees[i])
)
for i in range(len(greetees))
]
【讨论】:
【参考方案2】:这里的一个解决方案是使用Pool.apply
or Pool.apply_async
:
greetings = list(
multiprocessing.Pool(2).apply(greet, kwds='greetee': greetees[i])
for i in range(len(greetees))
)
for greeting in greetings:
print(greeting)
输出:
Hello, Foo!
Hello, Bar!
【讨论】:
这应该是公认的答案还是有更好的方法? 谢谢,我确实看到了这个答案,但不明白它与同样的问题有关。是的,这确实有效。我将发布另一个答案。 您应该在另一个问题中发帖。你同意你的本质上是重复的吗? 不,我不认为这些是重复的。他们尝试使用functools.partial
将3 个静态关键字参数(b
、c
、d
)和一个(a
)作为位置参数使用Pool.map
传递给函数。我不能做后者,因为我的函数的参数是关键字。因此,我只能使用 apply
或 apply_async
传递仅关键字参数。以上是关于如何将仅关键字参数应用于多处理池中的函数?的主要内容,如果未能解决你的问题,请参考以下文章
创建函数-----------(在函数中使用变量向函数传递参数在函数中处理变量关键字local)
如何将关键字参数添加到 Python 2.7 中的包装函数?