python - pygtk : free variable referenced before assignment in enclosing scope

标签 python programming-languages gtk closures semantics

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

    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 被覆盖,是否发生了一些奇怪的事情?

最佳答案

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

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

关于python - pygtk : free variable referenced before assignment in enclosing scope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1242593/

相关文章:

python - 如何使用pygtk拖动图像

python - python 中的多终端处理

python - Python 中的多输出多类机器学习

python - 如何最有效地检查列表中的唯一元素?

c - Cython 是否支持三元样式的 if 语句 (if ? then : else)?

c - getchar() 和 putchar()

c++ - 使用 C 或 C++ 编写 Linux shell

c - 如何在GEdit中获得GTK语法高亮?

c++ - 在 zlib1.dll 中找不到入口点 deflateSetHeader

python - 映射字典和列表 python