2010-07-01 54 views
1

在下面的代碼中,我打算有兩個按鈕,分別將'0'和'1'分別打印到標準輸出時。然而,當程序運行時,它們都會打印出'1',這是我在迭代中的最後一個值。爲什麼?Python的lambda迭代不能按預期工作

import Tkinter as tk 
import sys 

root = tk.Tk() 

for i in range(0,2): 
    cmd = lambda: sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'" % i,command=cmd).pack() 

root.mainloop() 

回答

5

i在您創建時不會捕獲到lambda表達式中(如您所願)。相反,這兩個函數都會引用外部for循環中的i,該函數在創建函數之後以及運行之前發生更改。要捕捉它,你可以使用默認值:

for i in range(0,2): 
    cmd = lambda i=i: sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'" % i,command=cmd).pack() 
3

當然它的問題

On lambdas, capture, and mutability

是一遍又一遍地來了......

+0

物品爲不相關的蟒蛇 – newacct 2010-07-01 07:00:26

+1

它鏈接到Python的兩個類似StackOverflow的問題,這個問題超越與Lambda和mutables大多數語言。 – Brian 2010-07-01 07:15:00

1

我覺得這是一個有點奇怪的是使用一個匿名函數然後給它一個名字。爲什麼不把它寫成這樣?

for i in 0,1: 
    def cmd(): 
     return sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'"%i, command=cmd).pack() 
+1

@newacct:「for i in 0,1」是正確的語法。在交互式Python shell中嘗試一下,看看會發生什麼。 – Deestan 2010-07-01 08:56:54