Как " NameError: свободная переменная 'var', на которую ссылаются перед назначением в заключительной области", может происходить в реальном коде?

пока я болтался в чат Python, кто-то зашел и сообщил следующее исключение:

NameError: free variable 'var' referenced before assignment in enclosing scope

Я никогда не видел это сообщение об ошибке раньше, и пользователь предоставил только небольшой фрагмент кода, который не мог вызвать ошибку сам по себе, поэтому я пошел в гугл за информацией, и ... кажется, их не так уж много. Пока я искал, пользователь сообщил, что их проблема решена как "проблема пробелов", а затем оставил комната.

поиграв немного, я смог воспроизвести исключение только с помощью кода игрушки, как это:

def multiplier(n):
    def multiply(x):
        return x * n
    del n
    return multiply

что дает мне:

>>> triple = multiplier(3)
>>> triple(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in multiply
NameError: free variable 'n' referenced before assignment in enclosing scope

все хорошо и хорошо, но мне трудно понять, как это исключение может произойти в дикой природе, учитывая, что мой пример выше

  1. глупо
  2. вряд ли произойдет случайно

... но очевидно, что при докладе я упоминается в начале этого вопроса.

Так как can это конкретное исключение происходит в реальном коде?

1 ответов


подумайте о более сложной функции, где n привязан в зависимости от некоторого условия, или нет. Вы не должны del имя, о котором идет речь, также происходит, если компилятор видит назначение, поэтому имя локально, но путь кода не берется, и имя никогда ничего не назначается. Еще один глупый пример:

def f():
    def g(x):
        return x * n
    if False:
        n = 10
    return g