A resposta para isso é dependente da versão e da situação. A resposta mais geral para versões recentes do Python (desde 3.3) foi descrita pela primeira vez abaixo por JF Sebastian . 1 Ele usa o Pool.starmap
método, que aceita uma sequência de tuplas de argumento. Em seguida, descompacta automaticamente os argumentos de cada tupla e os passa para a função fornecida:
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', ...
Para versões anteriores do Python, você precisará escrever uma função auxiliar para descompactar os argumentos explicitamente. Se você deseja usar with
, também precisará escrever um wrapper para se transformar Pool
em um gerenciador de contexto. (Obrigado ao muon por apontar isso.)
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', ...
Em casos mais simples, com um segundo argumento fixo, você também pode usar partial
, mas apenas no 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. Muito disso foi inspirado em sua resposta, que provavelmente deveria ter sido aceita. Mas como este está preso no topo, parecia melhor melhorá-lo para futuros leitores.
partial
nemlambda
fazer isso. Eu acho que tem a ver com a maneira estranha como as funções são passadas para os subprocessos (viapickle
).