Відповідь на це залежить від версії та ситуації. Найбільш загальну відповідь на останні версії 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
).