2015-07-22 15 views
5

Voglio avvolgere una funzione con argomenti specificati, qualcosa di simile functools.partial, ma non funziona come previsto:non è riuscito ad avvolgere funzione con lambda

source_codes = (0, 1, 2) 

def callback(source, *args): 
    print 'callback from source: ', source 

funcs = [] 
for source in source_codes: 
    funcs.append(lambda *args: callback(source, *args)) 

for i, func in enumerate(funcs): 
    print 'source expected: ', i 
    func() 
    print 

l'output:

source expected: 0 
callback from source: 2 

source expected: 1 
callback from source: 2 

source expected: 2 
callback from source: 2 

Ma ... Quello che voglio è:

source expected: 0 
callback from source: 0 

source expected: 1 
callback from source: 1 

source expected: 2 
callback from source: 2 

so che funziona se uso functools.partial, ma voglio sapere esimo e vero problema nel mio codice ... Il wrapper lambda usa una variabile globale source?

risposta

4

Il problema nel codice è che l'espressione lambda non viene valutata fino a quando non viene chiamata.

E quindi quando viene chiamato, utilizza l'ultimo valore di source. Non associa il valore di source al momento della creazione della lambda.

codice di esempio per mostrare questo comportamento -

>>> y = lambda: z 
>>> z = 0 
>>> y() 
0 
>>> z = 1 
>>> y() 
1 
2

partial già "congela" argomenti e/o parole chiave e gli dissero della funzione in modo da poter semplicemente eliminare lambda espressione:

source_codes = (0, 1, 2) 

def callback(source, *args): 
    print 'callback from source: ', source 

funcs = [] 
for source in source_codes: 
    funcs.append(partial(callback, source)) 
    source = 30 # don't have any effects over partial function. 

for i, func in enumerate(funcs): 
    print 'source expected: ', i 
    func() 
    print 
Problemi correlati