2009-08-07 49 views
6

非常奇怪的範圍錯誤,我甚至看不到。內部的更新功能的,我有一個嵌套的輔助函數來...幫助瓦特/某事:pygtk:在封閉範圍內賦值前引用的自由變量

def attach_row(ws,r1,r2): 
     es = [] 
     for i,w in enumerate(ws): 
      eb = gtk.EventBox() 
      a = gtk.Alignment(xalign=0.0,yalign=0.5) 
      a.add(w) 
      eb.add(a) 
      eb.set_style(self.rowStyle.copy()) 
      es.append(eb)     
      self.table.attach(eb, i, i+1, r1, r2, 
           xoptions=gtk.EXPAND|gtk.FILL, 
           yoptions=gtk.SHRINK) 

     def ene(_,ev): 
      for eb in es: 
       eb.set_state(gtk.STATE_PRELIGHT) 
     def lne(_,ev): 
      for eb in es: 
       eb.set_state(gtk.STATE_NORMAL) 
     for eb in es:     
      eb.connect('enter-notify-event', ene) 
      eb.connect('leave-notify-event', lne) 

這一段時間工作的一次,但如果更新()函數運行太多了,我最終得到:

for eb in es: 
NameError: free variable 'es' referenced before assignment in enclosing scope 

是什麼原因造成的?在這些函數被調用之前,es是最可靠的。這不正確嗎?有一些奇怪的事情發生在某些原因,在創建新創建時,先前創建的行的ene()會被調用,並且關閉的es會被覆蓋?

回答

4

確實很神祕 - 看起來封閉的內在功能正在消失。不知道是否與有關如何 pygtk擁有這樣的回調函數(我不熟悉它的內部)。試圖探索這個問題 - 如果您還將ene和lne添加到attach_row末尾的全局列表中,只是爲了確保它們在某個地方「正常」存在,以便它們的關閉能夠存活,會發生什麼情況 - 問題是否會持續存在那種情況?

如果確實如此,那麼我不得不承認這個問題太神祕了,並且同意以前的回答,作爲一種解決方法,使用可調參數來保持其狀態更清晰(我建議使用兩個綁定方法的一個類實例,因爲它們共享它們的狀態,但是具有__call__的一個類的兩個實例並且接收到要設置的狀態並且其__init__中的事件框列表當然也是合理的 - 具有兩個單獨的類恕我直言將是輕微的誇張;-)。

+0

hehe,true。我實際上意識到我有一個更好的方法來做到這一點 - 而不是刪除和附加很多這些行,我只是創建一組並更改其中的小部件。 儘管如此:我嘗試將「es」作爲用戶數據傳遞給這些ene和lne函數。發生什麼是我不再有NameError,但小工具根本不會突出顯示。 SOmething仍然在某處丟失。 如果這再次出現,我會嘗試類的想法。 – Claudiu 2009-08-07 06:08:44

+0

甚至更​​好的方法 - 使用VBox,每行放一個事件框,然後使用sizegroup來對齊列 – Claudiu 2009-08-07 07:07:01

+0

是的,這是在其他情況下發生的。我認爲是蟒蛇2.5怪異。仍然沒有找到答案 – Claudiu 2010-11-29 21:39:55

0

沒有足夠的點離開這個作爲註釋(剛註冊)...

  • 沒有「ES」全局變量或更高的範圍是什麼?
  • attach_row不是嵌套函數嗎?
  • NameError異常指向循環線在ene或lne函數?

一個可能的,但icky的解決方法可能是通過__call __()方法將實例化並可作爲函數調用的ene和lne類。

相關問題