Die Antwort auf diese Frage ist versions- und situationsabhängig. Die allgemeinste Antwort für neuere Versionen von Python (seit 3.3) wurde im Folgenden erstmals von J.F. Sebastian . 1 Sie verwendet die Pool.starmap
Methode, die eine Folge von Argumenttupeln annimmt. Sie packt dann automatisch die Argumente aus jedem Tupel aus und übergibt sie an die angegebene Funktion:
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', ...
Für frühere Versionen von Python müssen Sie eine Hilfsfunktion schreiben, um die Argumente explizit zu entpacken. Wenn Sie Folgendes verwenden möchten with
müssen Sie auch einen Wrapper schreiben, um die Pool
in einen Kontextmanager. (Dank an Myon für den Hinweis darauf).
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', ...
In einfacheren Fällen, mit einem festen zweiten Argument, können Sie auch partial
aber nur in 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. Vieles davon wurde durch seine Antwort inspiriert, die wahrscheinlich stattdessen hätte akzeptiert werden sollen. Aber da diese Antwort an der Spitze steht, schien es mir am besten, sie für künftige Leser zu verbessern.
12 Stimmen
Zu meiner Überraschung konnte ich weder die
partial
nochlambda
dies tun. Ich denke, es hat mit der seltsamen Art und Weise zu tun, wie Funktionen an die Unterprozesse übergeben werden (überpickle
).15 Stimmen
@senderle: Dies ist ein Fehler in Python 2.6, der aber mit 2.7 behoben wurde: bugs.python.org/issue5228
3 Stimmen
Ersetzen Sie einfach
pool.map(harvester(text,case),case, 1)
von:pool.apply_async(harvester(text,case),case, 1)
5 Stimmen
@Syrtis_Major , bitte editieren Sie keine OP-Fragen, die Antworten, die bereits gegeben wurden, effektiv verdrehen. Hinzufügen von
return
àharvester()
hat die Antwort von @senderie als ungenau bezeichnet. Das ist für künftige Leser nicht hilfreich.3 Stimmen
Ich würde sagen, eine einfache Lösung wäre, alle Args in ein Tupel zu packen und es in der ausführenden Funktion zu entpacken. Ich habe dies getan, wenn ich komplizierte mehrere Args an eine Funktion senden musste, die von einem Pool von Prozessen ausgeführt wird.
0 Stimmen
Vielleicht gibt es eine gewisse Komplexität, die ich für diesen speziellen Anwendungsfall vermisse, aber ein Teil funktioniert für meinen ähnlichen Anwendungsfall und ist sehr prägnant und einfach zu verwenden. python.omics.wiki/multiprocessing_map/