一个函数returns另一个函数。为什么里面的函数可以作用于父级的列表而不是常量?

A function returns another function. Why the function inside can scope a list from the parent but not a constant?

考虑这个函数:

def g():
    x = []
    
    def f():
        x.append([0])
        print(x)
        pass
    return f

调用它:

test = g()
test()

我得到以下输出:

Out: [[0]]

我们可以重新初始化测试函数并多次调用它:

test = g()
for i in range(3):
    test()

导致以下输出:

Out: [[0]]
[[0], [0]]
[[0], [0], [0]]

但是,定义如下函数:

def j():
    x = 1
    def f():
        x += 1
        print(x)
        pass
    return f

并调用它:

test = j()
test()

结果出错:

UnboundLocalError: local variable 'x' referenced before assignment

列表似乎在内部函数范围内,而值不在。为什么会这样?

这是因为j使用赋值表达式,而g使用方法调用。请记住 x += 1 等同于 x = x + 1。如果将 g 更改为:

def g():
    x = []

    def f():
        x += [[0]]
        print(x)
        pass
    return f

你得到:

>>> test = g()
>>> test()
Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    test()
  File "<pyshell#18>", line 5, in f
    x += [[0]]
UnboundLocalError: local variable 'x' referenced before assignment

@rassar 把原因说清楚了。这里我给出一个解决方案:

def j():
    x = 1
    def f():
        nonlocal x
        x += 1
        print(x)
        pass
    return f

其实这不是一个简单的问题。即使 += 看起来像一个有界方法调用,一个 in-place 操作(如果您有其他语言的经验)。但是下面运行的是 x = x.__add__(1)x = x.__iadd__(1) 之类的东西。所以这是一个作业。

因为,python 编译器知道函数 f 中的变量 'x' 是函数 j 中不存在的局部变量。所以就出现了你上面提到的错误。

所以你应该使用非本地。请参考下面的link。