2011-01-28 4 views
32

J'ai la fonction suivante:Comment laisser Pool.map prendre une fonction lambda

def copy_file(source_file, target_dir): 
    pass 

Maintenant, je voudrais utiliser multiprocessing pour exécuter cette fonction à la fois:

p = Pool(12) 
p.map(lambda x: copy_file(x,target_dir), file_list) 

Le problème est , les lambda ne peuvent pas être marinés, donc cela échoue. Quelle est la manière la plus soignée (pythonique) de résoudre ce problème?

Répondre

45

Utilisez un objet de fonction:

class Copier(object): 
    def __init__(self, tgtdir): 
     self.target_dir = tgtdir 
    def __call__(self, src): 
     copy_file(src, self.target_dir) 

Pour exécuter votre Pool.map:

p.map(Copier(target_dir), file_list) 
+2

Merci, cela est bien ce que je avais besoin ! –

+1

Merci! Je souhaite vraiment qu'ils puissent prendre en fonction lambda! – yeelan

15

La réponse ci-dessous a été frappé parce que ce does not actually work dans python2 depuis functools.partial objets (en python2) ne sont pas picklable.

functools.partial Cependant, les objets ont été rendus picklable dans Python3, donc cette solution fonctionne là.


Vous pouvez utiliser functools.partial:

import functools 
copier=functools.partial(copy_file,target_dir=target_dir) 
p.map(copier,file_list) 

+0

Celui-ci semble même plus propre ... Je déciderai plus tard lequel faire ma réponse –

+0

@Peter Smit: Oups - vous avez vu mon message avant que je l'ai supprimé ... Je suis en train de rétablir cela juste pour annoncer qu'il ne fait pas travailler en raison d'un bug dans Python2. – unutbu

+0

Ah, d'accord. Je regardais dans les documents et je n'ai pas vu un commentaire sur la sélection, alors j'ai supposé qu'ils étaient ... Je vais accepter l'autre réponse alors, car cela semble être la voie à suivre. –

0

La question est un peu vieux, mais si vous utilisez encore Python 2 ma réponse peut être utile. Trick est d'utiliser une partie du projet pathos: multiprocess fourche de multitraitement. Il se débarrasser de la limitation ennuyeuse du multiprocessus original.

Installation: pip install multiprocess

Utilisation:

>>> from multiprocess import Pool 
>>> p = Pool(4) 
>>> print p.map(lambda x: (lambda y:y**2)(x) + x, xrange(10)) 
[0, 2, 6, 12, 20, 30, 42, 56, 72, 90] 
0

De this réponse, pathos nous allons vous exécutez directement votre lambda p.map(lambda x: copy_file(x,target_dir), file_list), enregistrant toutes les solutions de contournement/hacks

Questions connexes