Відповідь на це залежить від версії та ситуації. Найбільш загальну відповідь на останні версії Python (починаючи з 3.3) вперше описав Дж . Ф. Себастьян . 1 Він використовує Pool.starmapметод, який приймає послідовність кортежів аргументів. Потім він автоматично розпаковує аргументи з кожного кортежу і передає їх заданій функції:
import multiprocessing
from itertools import product
def merge_names(a, b):
return '{} & {}'.format(a, b)
if __name__ == '__main__':
names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
with multiprocessing.Pool(processes=3) as pool:
results = pool.starmap(merge_names, product(names, repeat=2))
print(results)
# Output: ['Brown & Brown', 'Brown & Wilson', 'Brown & Bartlett', ...
Для більш ранніх версій Python вам потрібно буде написати допоміжну функцію, щоб явно розпакувати аргументи. Якщо ви хочете використовувати with, вам також потрібно написати обгортку, щоб перетворитись Poolна контекстний менеджер. (Дякую Мюону, що вказав на це.)
import multiprocessing
from itertools import product
from contextlib import contextmanager
def merge_names(a, b):
return '{} & {}'.format(a, b)
def merge_names_unpack(args):
return merge_names(*args)
@contextmanager
def poolcontext(*args, **kwargs):
pool = multiprocessing.Pool(*args, **kwargs)
yield pool
pool.terminate()
if __name__ == '__main__':
names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
with poolcontext(processes=3) as pool:
results = pool.map(merge_names_unpack, product(names, repeat=2))
print(results)
# Output: ['Brown & Brown', 'Brown & Wilson', 'Brown & Bartlett', ...
У більш простих випадках, з фіксованим другим аргументом, ви також можете використовувати partial, але тільки в Python 2.7+.
import multiprocessing
from functools import partial
from contextlib import contextmanager
@contextmanager
def poolcontext(*args, **kwargs):
pool = multiprocessing.Pool(*args, **kwargs)
yield pool
pool.terminate()
def merge_names(a, b):
return '{} & {}'.format(a, b)
if __name__ == '__main__':
names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
with poolcontext(processes=3) as pool:
results = pool.map(partial(merge_names, b='Sons'), names)
print(results)
# Output: ['Brown & Sons', 'Wilson & Sons', 'Bartlett & Sons', ...
1. Багато чого з цього надихнула його відповідь, яку, напевно, слід було прийняти замість цього. Але оскільки цей застряг у верхній частині, здавалося, найкраще вдосконалити його для майбутніх читачів.
partialніlambdaзробити цього. Я думаю, що це стосується дивного способу передачі функцій підпроцесам (черезpickle).