La réponse à cette question dépend de la version et de la situation. La réponse la plus générale pour les versions récentes de Python (depuis 3.3) a d'abord été décrite ci-dessous par JF Sebastian . 1 Il utilise la Pool.starmapméthode, qui accepte une séquence de tuples d'argument. Il décompresse ensuite automatiquement les arguments de chaque tuple et les transmet à la fonction donnée:
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', ...
Pour les versions antérieures de Python, vous devrez écrire une fonction d'assistance pour décompresser explicitement les arguments. Si vous souhaitez l'utiliser with, vous devrez également écrire un wrapper pour le transformer Poolen gestionnaire de contexte. (Merci à muon de l' avoir signalé.)
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', ...
Dans les cas plus simples, avec un second argument fixe, vous pouvez également utiliser partial, mais uniquement dans 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. Une grande partie de cela a été inspirée par sa réponse, qui aurait probablement dû être acceptée à la place. Mais comme celui-ci est coincé au sommet, il semblait préférable de l'améliorer pour les futurs lecteurs.
partialnilambdafaire ça. Je pense que cela a à voir avec l'étrange façon dont les fonctions sont transmises aux sous-processus (viapickle).