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.starmap
mé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 Pool
en 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.
partial
nilambda
faire ça. Je pense que cela a à voir avec l'étrange façon dont les fonctions sont transmises aux sous-processus (viapickle
).