2011-01-28 6 views
32

Ho la seguente funzione:Come lasciare Pool.map prendere una funzione lambda

def copy_file(source_file, target_dir): 
    pass 

Ora vorrei usare multiprocessing per eseguire questa funzione in una sola volta:

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

Il problema è , Lambda's non può essere in salamoia, quindi questo fallisce. Qual è il modo più accurato (pitonico) per risolvere questo problema?

risposta

45

Utilizzare un oggetto funzione:

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

Per eseguire il Pool.map:

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

Grazie, questo è davvero quello che mi serviva ! –

+1

Grazie! Spero davvero che possano prendere in funzione lambda! – yeelan

15

La risposta che segue è stata colpita perché questo does not actually work in python2 dal functools.partial oggetti (in python2) non sono serializzabili.

functools.partial Gli oggetti sono stati resi selezionabili in Python3, tuttavia, questa soluzione non funziona.


Potreste usare functools.partial:

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

+0

Questo sembra ancora più pulito ... Deciderò più tardi quale rispondere alla mia risposta –

+0

@Peter Smit: Oops: hai visto il mio post prima che lo cancellassi ... Sto annullando l'eliminazione solo per annunciarlo funziona a causa di un bug in Python2. – unutbu

+0

Ah, ok. Stavo guardando i documenti e non ho visto un commento sulla selezionabilità, quindi ho pensato che fossero ... Accetterò l'altra risposta allora, dato che sembra essere la strada da percorrere. –

0

domanda è un po 'vecchio, ma se si sta ancora utilizzare Python 2 la mia risposta può essere utile.

Trucco utilizza parte del progetto pathos: multiprocess fork di multiprocessing. Si sbarazza della fastidiosa limitazione del multiprocesso originale.

installazione: pip install multiprocess

Usage:

>>> 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

Da this risposta, il pathos diamo si esegue il lambda p.map(lambda x: copy_file(x,target_dir), file_list) direttamente, risparmiando tutte le soluzioni alternative/hack