这点 Python 不行:
def make_incrementer(start):
def closure():
# I know I could write 'x = start' and use x - that's not my point though (:
while True:
yield start
start += 1
return closure
x = make_incrementer(100)
iter = x()
print iter.next() # Exception: UnboundLocalError: local variable 'start' referenced before assignment
我知道如何解决这个错误,但请耐心等待:
这段代码运行良好:
def test(start):
def closure():
return start
return closure
x = test(999)
print x() # prints 999
为什么我可以读取闭包内的 start
变量但不能写入?
什么语言规则导致对 start
变量的这种处理?
更新:我发现这篇 SO 帖子相关(答案比问题更重要):Read/Write Python Closures
最佳答案
每当您在函数内部分配变量时,它将是该函数的局部变量。 start += 1
行正在为 start
分配一个新值,因此 start
是一个局部变量。由于存在局部变量 start
,因此当您第一次尝试访问它时,该函数不会尝试在全局范围内查找 start
,因此您会看到错误。
在 3.x 中,如果您使用 nonlocal
关键字,您的代码示例将起作用:
def make_incrementer(start):
def closure():
nonlocal start
while True:
yield start
start += 1
return closure
在 2.x 上,您通常可以通过使用 global
关键字来解决类似的问题,但这在这里不起作用,因为 start
不是全局变量。
在这种情况下,您可以执行建议的操作 (x = start
),也可以使用可变变量修改并生成内部值。
def make_incrementer(start):
start = [start]
def closure():
while True:
yield start[0]
start[0] += 1
return closure
关于python - 为什么这个闭包不修改封闭范围内的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7535857/