一个函数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。
考虑这个函数:
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。