怎么能" NameError:自由变量' var'在封闭范围内转让前引用"在实际代码中出现?

时间:2014-07-11 22:12:22

标签: python exception scope closures free-variable

当我在Python chatroom闲逛时,有人进入并报告了以下异常:

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

我之前从未见过这个错误消息,并且用户只提供了一个本身无法导致错误的小代码片段,所以关闭我google搜索信息,然后......似乎并不多。在我搜索时,用户报告他们的问题已经解决为"空白问题",然后离开了房间。

玩了一下后,我只能用这样的玩具代码重现异常:

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. 不太可能偶然发生
  3. ...但显然确实如此,考虑到我在本期问题开头提到的报告。

    那么如何这个特定的异常会在实际代码中出现?

1 个答案:

答案 0 :(得分:5)

考虑一个更复杂的函数,其中n取决于某些条件而不受约束。您不必del有问题的名称,如果编译器看到一个赋值,也会发生这种情况,因此名称是本地的,但代码路径不会被采用,名称永远不会分配任何东西。另一个愚蠢的例子:

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