pygtk: свободная переменная, на которую ссылаются перед присваиванием в окружающем объеме - PullRequest
6 голосов
/ 07 августа 2009

Очень странная ошибка при просмотре, которую я даже не вижу. Внутри функции обновления у меня есть вложенная вспомогательная функция, чтобы ... помочь с чем-то:

    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, безусловно, назначается до того, как эти функции будут вызваны. Разве это не правильно? Случается ли какая-то странная вещь, когда по какой-то причине ен () для ранее созданной строки вызывается во время создания новой, а закрытое значение es перезаписывается?

Ответы [ 2 ]

4 голосов
/ 07 августа 2009

Довольно загадочно - похоже, закрытие исчезает из-под внутренних функций. Интересно, связано ли это с как pygtk содержит такие функции обратного вызова (я не знаком с его внутренними компонентами). Чтобы попытаться выяснить это - что произойдет, если вы добавите ены и lne к глобальному списку в конце attach_row, просто чтобы убедиться, что они где-то «нормально» хранятся, чтобы их закрытие сохранилось - решает проблему сохраняться в этом случае?

Если это так, то я должен признать, что проблема просто СЛИШКОМ загадочная, и согласиться с предыдущим ответом, предлагая в качестве обходного пути использование вызываемых элементов, которые более четко поддерживают свое состояние (я бы предложил два связанных один экземпляр класса, так как они совместно используют свое состояние, но два экземпляра одного класса с __call__ и получение состояния для установки и списка блоков событий в его __init__, безусловно, также разумно - наличие двух отдельных классов IMHO будет будет небольшое преувеличение; -).

0 голосов
/ 07 августа 2009

Не хватает баллов, чтобы оставить это как комментарий (только что зарегистрировался) ...

  • Нет переменной 'es' глобально или в более широком контексте?
  • attach_row также не является вложенной функцией?
  • Исключение NameError указывает на строку цикла в функциях ена или lne?

Один из возможных, но странных обходных путей может заключаться в создании классов ена и lne, которые создаются и могут вызываться как функции с помощью метода __call __ ().

...