python 3.x 中的闭包和变量范围问题让我感到困惑
Closure and variable scope in python 3.x issue causing me confusion
我正在使用 Python 3.7.0,我正在做一些实验以理解变量范围的微妙之处,但我仍然不理解这种行为。
当我执行这段代码时:
def f():
x=0
def g():y=x+1;x=y
return g
f()()
我得到 UnboundLocalError: 局部变量 'x' 在赋值前被引用
但是当我执行这个时:
def f():
x=0
def g():y=x+1
return g
f()()
它工作正常。甚至这个:
def f():
x=0
def g():x=1
return g
f()()
它也很好用。所以我很困惑。在我看来,如果将值 1
分配给 g
函数中的非局部变量 x
单独工作正常,另一方面,如果将包含 x
的表达式分配给函数 g
中的局部变量 y
也可以正常工作,那么指令 y=x+1
和 x=y
应该都可以工作。我不明白是什么导致了错误。我觉得我在理解 Python 的行为时遗漏了一些基本的东西。
我会采取不明智的做法。在以下代码中:
def f():
x = 0 # assignment makes this x local to f()
def g():
y = x + 1
x = y # assignment makes this x local to g()
return g
f()()
g()
中 x
的赋值强制它成为 g()
的局部变量。因此,当您访问未分配的本地值时,第一行会导致错误。我相信这个 "assignment makes it local" 逻辑不遵循您的程序流程——函数被视为一个整体来做出这个决定,然后逐行查看代码。
您可以从函数访问范围内的任何变量,但只能设置局部变量。除非您已将要分配的变量声明为 global
或 nonlocal
:
def f():
x = 0 # assignment makes this x local to f()
def g():
nonlocal x
y = x + 1
x = y # x is declared to come from a nonlocal scope
return g
f()()
在你的第二个例子中,这不是问题,因为你只查看 x
的值,而不是设置它,因此它可以来自任何适当的范围:
def f():
x = 0 # assignment makes this x local to f()
def g():
y = x + 1 # x comes from an outer scope
return g
f()()
最后,您的第三个示例与第一个示例相同,没有无符号局部变量使用错误:
def f():
x = 0 # assignment makes this x local to f()
def g():
x = 1 # assignment makes this x local to g()
return g
f()()
It seems to me that if assigning the value 1 to the nonlocal variable
x in the g function works fine alone
您如何确定 f()
中 x
的重新分配工作正常?
我正在使用 Python 3.7.0,我正在做一些实验以理解变量范围的微妙之处,但我仍然不理解这种行为。
当我执行这段代码时:
def f():
x=0
def g():y=x+1;x=y
return g
f()()
我得到 UnboundLocalError: 局部变量 'x' 在赋值前被引用
但是当我执行这个时:
def f():
x=0
def g():y=x+1
return g
f()()
它工作正常。甚至这个:
def f():
x=0
def g():x=1
return g
f()()
它也很好用。所以我很困惑。在我看来,如果将值 1
分配给 g
函数中的非局部变量 x
单独工作正常,另一方面,如果将包含 x
的表达式分配给函数 g
中的局部变量 y
也可以正常工作,那么指令 y=x+1
和 x=y
应该都可以工作。我不明白是什么导致了错误。我觉得我在理解 Python 的行为时遗漏了一些基本的东西。
我会采取不明智的做法。在以下代码中:
def f():
x = 0 # assignment makes this x local to f()
def g():
y = x + 1
x = y # assignment makes this x local to g()
return g
f()()
g()
中 x
的赋值强制它成为 g()
的局部变量。因此,当您访问未分配的本地值时,第一行会导致错误。我相信这个 "assignment makes it local" 逻辑不遵循您的程序流程——函数被视为一个整体来做出这个决定,然后逐行查看代码。
您可以从函数访问范围内的任何变量,但只能设置局部变量。除非您已将要分配的变量声明为 global
或 nonlocal
:
def f():
x = 0 # assignment makes this x local to f()
def g():
nonlocal x
y = x + 1
x = y # x is declared to come from a nonlocal scope
return g
f()()
在你的第二个例子中,这不是问题,因为你只查看 x
的值,而不是设置它,因此它可以来自任何适当的范围:
def f():
x = 0 # assignment makes this x local to f()
def g():
y = x + 1 # x comes from an outer scope
return g
f()()
最后,您的第三个示例与第一个示例相同,没有无符号局部变量使用错误:
def f():
x = 0 # assignment makes this x local to f()
def g():
x = 1 # assignment makes this x local to g()
return g
f()()
It seems to me that if assigning the value 1 to the nonlocal variable x in the g function works fine alone
您如何确定 f()
中 x
的重新分配工作正常?