2013-05-20 52 views
1

我目前正在嘗試創建一個會在dict中綁定事件動作對象的循環。 回調函數只是調用動作函數並打印參數。在循環中使用lambda表達式進行自動綁定

for binding, action in self.keyMap.revMap.items() : 
     print binding, action 
     self.top.bind(binding, 
         lambda event : self.callback(event, self.actionRep.__class__.__dict__[action])) 

    print self.top.bind() 

在綁定,我得到這些日誌:

<Escape> toggleMenu -------------generated by the line "print binding, action" 
<Return> toggleChat -------------generated by the line "print binding, action" 
('<Key-Return>', '<Key-Escape>', '<Key>') ---generated by the line "print self.top.bind()" 

上述事件動作夫婦是正確的。 然而,當事件發生時,我有這樣的:

<Tkinter.Event instance at 0x0000000002BB3988> <function toggleChat at 0x0000000002B60AC8> 
<Tkinter.Event instance at 0x0000000002BB3948> <function toggleChat at 0x0000000002B60AC8> 

是,無論是逃避和返回事件似乎是必然toggleChat ...

我有lambda表達式的一點經驗,但我希望爲每個循環創建一個新的無名函數。我錯了嗎?如果不是,問題在哪裏?

在此先感謝您的見解。

回答

3

爲Lambda表達式創建關閉成語是通過您希望通過默認參數綁定的對象

self.top.bind(binding, lambda event, action=action: self.callback(event, self.actionRep.__class__.__dict__[action])) 
2

讓我們在常規功能的行爲首先看看:

x = 2 
def foo(): 
    return x 

x = 3 
print foo() #3 

現在我們看到當一個函數從封閉的命名空間中獲取一個變量時,它會返回該變量的當前值,而不是函數定義時的值。然而,我們可以通過創建一個默認參數來強制它獲取值,因爲這些參數是在函數創建時計算的,而不是在函數被調用時計算的。

x = 2 
def foo(x=x): 
    return x 
x = 3 
print foo() #2 

lambda功能沒有什麼區別。在循環中創建新的無名函數,但是當您實際去評估函數時,您會在循環終止時獲取循環變量的值。爲了解決這個問題,我們只需要在創建函數時指定值:

funcs = [lambda i=i: i for i in range(10)] 
print funcs[3]() #3 
+0

感謝您的深刻見解:)。 – aPythonJourney

+0

@aPythonJourney - 當然。這是我認爲在蟒蛇之旅中幾乎每個人都會咬的東西之一。 – mgilson