這在Python FAQ解釋:Why do lambdas defined in a loop with different values all return the same result?。
引述常見問題的答案:
這是因爲x是不是本地的lambda表達式,但在外部範圍的定義,它是訪問時的拉姆達被調用 - 不是當它定義...
爲了避免這種情況,您需要保存在局部變量的lambda表達式的值,使它們不依賴於全球的價值...
換句話說,您的新功能不存儲的值i
,他們正在存儲變量i
。並且它們全部存儲相同的變量i
,在循環結束時它的值爲10
。實際上,如果您在F.mainloop()
之前添加i = 'spam'
,您會看到現在所有按鈕都打印出字符串spam
而不是數字。
當您嘗試創建可能影響其定義環境的閉包功能時,這非常有用。但是當您嘗試這樣做時,而不是可能會阻礙。
最簡單的方法是使用帶默認值的參數。默認值不包含變量;只是在函數定義時評估的值。所以:
newButton = Button(F,text="Show Number", command=lambda num=i: showNumber(num))
*請注意,在這種情況下,有沒有實際參與任何關閉,因爲i
是一個全球性的,而不是在封閉範圍內的局部。但實際上,這僅僅是因爲Python對全局變量有特殊的處理,並且在這裏不需要關閉;從概念上講,如果你想到有一個,你不會陷入任何麻煩,除非你開始看__closure__
或__code__
屬性。
非常感謝! :) – superyo40
這不太準確,因爲這裏實際上並不是封閉的。但這是一個比我的簡潔的解釋,希望更容易讓新手理解。 – abarnert
@abarnert:謝謝你提到它 - 這是一點技術性的東西,讓我喜歡StackOverflow,並在這個過程中學習。 – voithos