2015-07-22 11 views
5

मैं निर्दिष्ट तर्क, functools.partial की तरह कुछ के साथ एक समारोह रैप करने के लिए चाहते हैं के साथ समारोह लपेटो करने में विफल रहा है, लेकिन यह अपेक्षा के अनुरूप काम नहीं करता है:लैम्ब्डा

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 

उत्पादन:

source expected: 0 
callback from source: 2 

source expected: 1 
callback from source: 2 

source expected: 2 
callback from source: 2 

लेकिन ... क्या मैं चाहता हूँ है:

source expected: 0 
callback from source: 0 

source expected: 1 
callback from source: 1 

source expected: 2 
callback from source: 2 

मैं यह काम करता है अगर मैं functools.partial का उपयोग पता है, लेकिन मुझे पता है कि वें चाहते ई मेरे कोड में असली समस्या ... क्या लैम्ब्डा रैपर वैश्विक चर source का उपयोग करता है?

उत्तर

4

आपके कोड में समस्या यह है कि लैम्ब्डा अभिव्यक्ति का मूल्यांकन तब तक नहीं किया जाता जब तक इसे कॉल नहीं किया जाता।

और फिर जब इसे कॉल किया जाता है, तो यह source का नवीनतम मान उपयोग करता है। यह लैम्ब्डा के निर्माण के समय source के मूल्य को बाध्य नहीं करता है।

उदाहरण कोड इस व्यवहार को दिखाने के लिए -

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

पहले से ही "फ्रीज़" partiallambda अभिव्यक्ति समारोह के तर्कों और/या कीवर्ड आप उसे करने के लिए पारित कर दिया तो आप बस को खत्म कर सकते हैं:

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 
संबंधित मुद्दे