6

非常奇怪的范围界定错误,我什至看不到。在更新器函数内部,我有一个嵌套的辅助函数来...帮助 w/ 一些东西:

    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)

这偶尔会起作用,但如果 update() 函数运行太多,我最终会得到:

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

这是什么原因造成的?es 肯定是在调用这些函数之前分配的。不是吗?是否发生了一些奇怪的事情,由于某种原因,在创建新行时调用了先前创建的行的 ene(),而关闭的行es被覆盖了?

4

2 回答 2

4

确实很神秘——看起来闭包从内部函数下消失了。想知道这是否与pygtk如何拥有这样的回调函数有关(我不熟悉它的内部结构)。为了尝试对此进行调查-如果您还将 ene 和 lne 附加到末尾的全局列表中会发生什么attach_row,只是为了确保它们“正常”保存在某个地方以便它们的闭包存活下来-问题是否仍然存在案子?

如果确实如此,那么我不得不承认这个问题太神秘了,并且同意前面的答案,建议作为一种解决方法,使用以更清晰的方式保持其状态的可调用对象(我建议一个类实例的两个绑定方法,因为它们共享它们的状态,但是单个类的两个实例具有__call__并接收要设置的状态以及其中的事件框列表__init__当然也是合理的——恕我直言,拥有两个单独的类会有点夸张;-)。

于 2009-08-07T05:17:27.497 回答
0

没有足够的积分将此作为评论(刚刚注册)...

  • 全局或更高范围内没有“es”变量?
  • attach_row 也不是嵌套函数吗?
  • NameError 异常指向 ene 或 lne 函数中的循环行?

一种可能但令人讨厌的解决方法可能是使 ene 和 lne 类通过 __call__() 方法被实例化和调用为函数。

于 2009-08-07T03:47:44.633 回答