Python multitraitement de la piscine.carte pour de multiples arguments
Dans le Python de multitraitement de la bibliothèque, est-il une variante de la piscine.carte prenant en charge plusieurs arguments?
text = "test"
def harvester(text, case):
X = case[0]
text+ str(X)
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=6)
case = RAW_DATASET
pool.map(harvester(text,case),case, 1)
pool.close()
pool.join()
- À ma grande surprise, j'ai pu faire ni
partial
nilambda
ce faire. Je pense que cela a à voir avec la façon étrange que les fonctions sont transmis à la sous-processus (viapickle
). - C'est un bug dans la version 2.6 de Python, mais a été fixé 2.7: bugs.python.org/issue5228
- Tout simplement remplacer
pool.map(harvester(text,case),case, 1)
par:pool.apply_async(harvester(text,case),case, 1)
- merci de ne pas modifier OP questions qui biaiser les réponses qui ont été données auparavant. L'ajout de
return
àharvester()
tourné @senderie 's réponse en être infidèle. Ce qui n'aide pas les futurs lecteurs. - Je dirais que la solution facile serait de pack tous les arguments dans un tuple et décompressez-le dans l'exécution de la touche func. Je l'ai fait quand j'avais besoin d'envoyer compliqué de multiples arguments pour un func exécutée par un pool de processus.
Vous devez vous connecter pour publier un commentaire.
La réponse à cela est de la version, et selon la situation. La plupart de réponse générale pour les dernières versions de Python (depuis 3.3) a d'abord été décrit ci-dessous par J. F. Sebastian.1 Il utilise le
de la Piscine.starmap
méthode, qui accepte une séquence de l'argument des n-uplets. Ensuite, il décompresse automatiquement les arguments de chaque n-uplet et les transmet à la fonction donnée:Pour les versions antérieures de Python, vous devez écrire une fonction d'aide à déballer les arguments explicitement. Si vous souhaitez utiliser
with
, vous aurez également besoin d'écrire un wrapper pour activerPool
dans un gestionnaire de contexte. (Merci à muon pour le rappeler.)Dans les cas les plus simples, avec un deuxième argument, vous pouvez également utiliser
partial
, mais seulement dans Python 2.7+.1. Beaucoup de cela a été inspirée par sa réponse, qui doit probablement avoir été accepté à la place. Mais puisque celui-ci est coincé en haut, il a semblé préférable de les améliorer pour les futurs lecteurs.
=RAW_DATASET
valeur par défaut pourcase
. Sinonpool.map
va tromper sur les multiples arguments.text
variable dans votre exemple? Pourquoi est -RAW_DATASET
apparemment passé deux fois. Je pense que vous pourriez avoir une faute de frappe?with .. as ..
me donneAttributeError: __exit__
, mais fonctionne très bien si je viens de l'appelerpool = Pool();
puis fermez manuellementpool.close()
(python2.7)Pool
objets ne deviennent pas des gestionnaires de contexte jusqu'à ce que Python 3.3. J'ai ajouté un simple wrapper fonction qui retourne unPool
gestionnaire de contexte.pool.starmap(twoarg_func, zip(finite, infinite))
. Il est possible quepool.imap
etpool.imap_unordered
pouvait tolérer infini des générateurs mais qui sonne toujours comme un très mauvaise idée pour moi.Python 3.3 comprend
de la piscine.starmap()
méthode:Pour les anciennes versions:
De sortie
Avis comment
itertools.izip()
etitertools.répéter()
sont utilisés ici.En raison de le bug mentionné par @unutbu vous ne pouvez pas utiliser
functools.partielle()
ou des fonctionnalités similaires à la version 2.6 de Python, de sorte que la simple fonction wrapperfunc_star()
doit être définie de manière explicite. Voir aussi la solution de contournement proposé paruptimebox
.func_star
comme ceci:def func_star((a, b))
. Bien sûr, cela ne fonctionne que pour un nombre fixe d'arguments, mais si c'est le seul cas qu'il a, c'est plus lisible.func = lambda x: func(*x)
au lieu de définir une fonction wrapperfunc_star()
ci-dessus)starstarmap
.Je pense que le ci-dessous seront mieux
sortie
args
directement dansadd
, il fonctionne pour n'importe quel nombre d'arguments:def add(args): (x,y) = args
lambda
fonction au lieu de définirmulti_run_wrapper(..)
lambda
ne fonctionne pas carpool.map(..)
essaie de pickle la fonction donnéeadd
dans une liste?À l'aide de Python 3.3,+ avec
pool.starmap():
Résultat:
Vous pouvez également zip() plus d'arguments si vous le souhaitez:
zip(a,b,c,d,e)
Dans le cas où vous voulez avoir une constante de la valeur passée en argument, vous devez utiliser
import itertools
et puiszip(itertools.repeat(constant), a)
par exemple.Ayant appris itertools dans J. F. Sebastian réponse, j'ai décidé de franchir une nouvelle étape et d'écrire un
parmap
paquet qui prend garde à la parallélisation, offrantmap
etstarmap
fonctions sur python 2.7 et python 3.2 (et plus tard aussi) qui peut prendre n'importe quel nombre des arguments de position.Installation
Comment paralléliser:
J'ai téléchargé parmap de PyPI et à un github.
Comme un exemple, la question peut être répondu comme suit:
# "Comment prendre de multiples arguments".
Il y a une fourchette de
multiprocessing
appelé pathétique (remarque: utiliser la version sur github) qui n'a pas besoinstarmap
-- des fonctions de la carte miroir de l'API python de la carte, et donc de la carte peut prendre plusieurs arguments. Avecpathos
, vous pouvez généralement faire le multitraitement dans l'interprète, au lieu d'être coincé dans le__main__
bloc. Le Pathos est due pour une sortie, après une légère mise à jour-la plupart du temps la conversion de python 3.x.Vous pouvez utiliser les deux fonctions suivantes, afin d'éviter d'écrire un wrapper pour chaque nouvelle fonction:
Utiliser la fonction
function
avec les listes d'argumentsarg_0
,arg_1
etarg_2
comme suit:Une autre alternative simple est d'envelopper vos paramètres de fonction dans un tuple, puis les envelopper les paramètres doivent être passés dans les tuples ainsi. C'est peut-être pas l'idéal lorsque l'on traite avec de gros morceaux de données. Je crois qu'il serait faire des copies pour chaque tuple.
Donne la sortie dans quelques un ordre aléatoire:
Une meilleure solution pour python2:
2 3 4
1 2 3
0 1 2
out[]:
[3, 5, 7]
Une meilleure façon est d'utiliser décorateur au lieu d'écrire fonction wrapper à la main. Surtout quand vous avez beaucoup de fonctions de la carte, décorateur permettra d'économiser votre temps en évitant l'écriture de l'enveloppe pour chaque fonction. Généralement décoré de la fonction n'est pas picklable, mais nous pourrions utiliser
functools
de les contourner. Plus disscusions peut être trouvé ici.Ici l'exemple
Alors vous pouvez mapper avec zip arguments
Bien sûr, vous pouvez toujours utiliser
de la Piscine.starmap
en Python 3 (>=3.3) comme mentionné dans d'autres réponses.itertools.product
au lieu dezip
.Une autre façon est de passer d'une liste de listes à un seul argument de routine:
On peut que de construire une liste de listes d'arguments à la méthode préférée.
De python 3.4.4, vous pouvez utiliser le multitraitement.get_context() pour obtenir un objet de contexte à utiliser plusieurs méthodes:
Ou vous venez tout simplement de remplacer
par:
Il y a beaucoup de réponses ici, mais aucun ne semble à fournir Python 2/3 du code compatible qui fonctionnera sur n'importe quelle version. Si vous voulez que votre code travail juste, cela fonctionne, soit une version de Python:
Après cela, vous pouvez utiliser le multitraitement réguliers Python 3, mais vous l'aimez. Par exemple:
travaillera en Python 2 et Python 3.
Dans la documentation officielle indique qu'il prend en charge un seul objet iterable argument. J'aime utiliser apply_async dans de tels cas. Dans votre cas, je voudrais faire:
Ceci est un exemple de la routine que j'utilise pour passer plusieurs arguments à une fonction d'argument utilisé dans un piscine.imap fourche:
pour python2, vous pouvez utiliser cette astuce