Python3.x中的闭包和变量范围问题让我感到困惑
我正在使用Python3.7.0,我正在做一些实验来理解变量作用域的微妙之处,但我仍然不理解这种行为 当我执行此代码时:Python3.x中的闭包和变量范围问题让我感到困惑,python,function,variables,scope,closures,Python,Function,Variables,Scope,Closures,我正在使用Python3.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
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()()
它很好用。即使是这个:
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()
的局部变量。因此,当您访问未赋值局部变量的值时,第一行会导致错误。我相信这种“赋值使其成为局部”的逻辑并没有遵循程序的流程——函数被视为一个整体来进行判断,然后代码被逐行查看
您可以从函数访问作用域中的任何变量,但只能设置局部变量。除非已将分配的变量声明为全局
或非局部
:
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()()
在我看来,如果将值1赋给非局部变量
g函数中的x单独起作用
您是如何确定在
f()
中重新分配x
效果良好的?我将对此进行一次不明智的尝试。在以下代码中:
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()
的局部变量。因此,当您访问未赋值局部变量的值时,第一行会导致错误。我相信这种“赋值使其成为局部”的逻辑并没有遵循程序的流程——函数被视为一个整体来进行判断,然后代码被逐行查看
您可以从函数访问作用域中的任何变量,但只能设置局部变量。除非已将分配的变量声明为全局
或非局部
:
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()()
在我看来,如果将值1赋给非局部变量
g函数中的x单独起作用
您是如何确定在
f()
中重新分配x
效果良好的?“您是如何确定在f()中重新分配x效果良好的?”对不起,我认为这是非本地的,我的错。您的回答很清楚,非常感谢。我还认为python只考虑函数中第一次出现的变量来确定作用域。但你告诉我,它首先读取函数作为一个整体来确定每个变量的作用域,然后逐行执行。我还了解到,除非将变量声明为非本地变量,否则赋值会使其成为本地变量,即使前面的语句将其视为非本地变量(我的意思是从一个未赋值的变量中读取一个值会使python查找非局部范围)。请告诉我是否仍然缺少一些内容。“您是如何确定在f()中重新赋值x的工作正常的?”很抱歉,我认为它被认为是非局部的,我的错。您的回答很清楚,非常感谢。我还认为python只考虑函数中第一次出现的变量来确定作用域。但您告诉我,它首先读取函数作为一个整体来确定每个变量的作用域,然后执行第行通过这一行,我还了解到,除非将变量声明为非本地变量,否则给它赋值会使它成为本地变量,即使前面的语句将其视为非本地变量(我的意思是从未赋值的变量中读取值会使python查找非本地范围)。请告诉我是否仍然缺少某些内容。我所说的“经验”是指“实验”,我刚刚编辑了这个问题。对不起,我把英语和法语弄混了,两者都不是我的母语。我说的“经验”是指“实验”,我刚刚编辑了这个问题。对不起,我把英语和法语弄混了,两者都不是我的母语。