2015-11-15 58 views
3

我想創建一個由固定基本函數創建的函數對象組成的函數列表,但函數對象具有不同的輸入參數。我已經寫了這樣的代碼:Python中的函數對象

def f_base(name): 
    print "I am %s" % name 

f_list = [] 
for name in ['A', 'B']: 
    f_list.append(
     lambda : f_base(name) 
    ) 

f_list[0]() 
f_list[1]() 

結果是:

I am B 
I am B 

但我想:

I am A 
I am B 

有人能解釋爲什麼Python中產生這樣的輸出,什麼是最簡單的如何獲得我需要的結果?

回答

3

所有你與lambda功能,現在正呼籲在體內的變量namef_base做。 name變量是在您創建每個函數時調用那些lambda函數和而不是時確定的。

變量name在循環完成後引用'B',因爲在循環完成後,python會將for循環中定義的變量保留下來。

這是,如果你做的特別明顯,

name = 'C' 

循環後調用函數之前。然後你得到,

I am C 
I am C 

要做到你需要你想要創建一個閉合功能,或可能會更好,使用functools.partial

import functools 

def f_base(name): 
    print "I am %s" % name 

f_list = [] 
for name in ['A', 'B']: 
    f_list.append(
     functools.partial(f_base, name) 
    ) 

f_list[0]() 
f_list[1]() 

將會產生,

I am A 
I am B 
+0

亦稱臭名昭著「[後期綁定疑難雜症](http://docs.python-guide.org/en/latest/writing/gotchas/#late-綁定關閉)' – bereal

+0

太棒了!感謝你的回答! – Fomalhaut

1

您可以創建封閉:

def f_base(name): 
    def closure(): 
     print "I am %s" % name 
    return closure 

f_list = [] 
for name in ['A', 'B']: 
    f_list.append(f_base(name)) 
相關問題