Python 全局 variable/scope 混乱
Python global variable/scope confusion
我已经开始自学 python,并且注意到与全局变量和范围有关的一些奇怪的事情。
当我 运行 这个:
x = 2
y = 3
z=17
def add_nums():
y = 6
return z+y
打印出23的结果...
但是,当我将 return 扩展为:
x = 2
y = 3
z=17
def add_nums():
y = 6
z = z + y
return z
我在第 6 行收到以下错误:
Local name referenced but not bound to a value.
A local name was used before it was created. You need to define the
method or variable before you try to use it.
我很困惑为什么我会在这里收到错误,因为 z 是全局可访问的。
Python 通过绑定操作 确定范围。赋值是一种绑定操作,导入也是如此,在 except .. as
、with .. as
或 for
循环中使用名称作为目标,或者通过创建函数或 class。
当名称绑定在范围内时,它是该范围的本地名称。如果使用了名称但未绑定,则它是非本地的;编译器将在编译时确定范围应该是什么。在您的情况下,除了全局范围外没有父范围,因此任何未绑定的名称都被视为全局名称。
由于您的第二个示例绑定到 z
(您使用了 z =
,一个赋值),该名称是函数的局部名称。
如果一个名称绑定在一个范围内,但您想告诉 Python 它应该是全局的,您需要明确地这样做:
x = 2
y = 3
z=17
def add_nums():
global z
y = 6
z = z + y
return z
global z
行告诉编译器 z
应该是全局的,即使您绑定到它。
当变量在等号左边时python会创建一个局部变量。当变量在等号右边时 python 会尝试寻找一个局部变量,如果他找不到,那么它会使用一个全局变量。在您的示例中,z 位于等号的右侧和左侧,以避免歧义 python 引发错误。您需要使用 global
语法来避免这种情况:
x = 2
y = 3
z=17
def add_nums():
global z
y = 6
z = z + y
return z
如果你想让函数体内的名字y
和z
引用你的全局变量当你给它们赋值时,你必须声明他们是这样的:
x = 2
y = 3
z=17
def add_nums():
global y
global z
y = 6
z = z + y
return z
否则,当您在函数内部对变量 y
和 z
进行赋值时,您会创建仅存在于函数局部范围内的不同名称。
正如评论中所指出的,您可以引用一个全局变量,如果它是可变的(即向列表中添加一些内容),您甚至可以修改它,只要您不尝试将其分配给它。
我们来分析标记线。
x = 2
y = 3
z = 17
def add_nums():
y = 6
z = z + y <--- THIS LINE
return z
z ...创建了一个新的局部变量
= ...我们要给它赋值
z ... 这个变量存在(新的本地变量)但它还没有值。
+ y ...这部分没到
结果是一条错误消息 "UnboundLocalError: local variable 'z' referenced before assignment"。
我已经开始自学 python,并且注意到与全局变量和范围有关的一些奇怪的事情。 当我 运行 这个:
x = 2
y = 3
z=17
def add_nums():
y = 6
return z+y
打印出23的结果... 但是,当我将 return 扩展为:
x = 2
y = 3
z=17
def add_nums():
y = 6
z = z + y
return z
我在第 6 行收到以下错误:
Local name referenced but not bound to a value.
A local name was used before it was created. You need to define the
method or variable before you try to use it.
我很困惑为什么我会在这里收到错误,因为 z 是全局可访问的。
Python 通过绑定操作 确定范围。赋值是一种绑定操作,导入也是如此,在 except .. as
、with .. as
或 for
循环中使用名称作为目标,或者通过创建函数或 class。
当名称绑定在范围内时,它是该范围的本地名称。如果使用了名称但未绑定,则它是非本地的;编译器将在编译时确定范围应该是什么。在您的情况下,除了全局范围外没有父范围,因此任何未绑定的名称都被视为全局名称。
由于您的第二个示例绑定到 z
(您使用了 z =
,一个赋值),该名称是函数的局部名称。
如果一个名称绑定在一个范围内,但您想告诉 Python 它应该是全局的,您需要明确地这样做:
x = 2
y = 3
z=17
def add_nums():
global z
y = 6
z = z + y
return z
global z
行告诉编译器 z
应该是全局的,即使您绑定到它。
当变量在等号左边时python会创建一个局部变量。当变量在等号右边时 python 会尝试寻找一个局部变量,如果他找不到,那么它会使用一个全局变量。在您的示例中,z 位于等号的右侧和左侧,以避免歧义 python 引发错误。您需要使用 global
语法来避免这种情况:
x = 2
y = 3
z=17
def add_nums():
global z
y = 6
z = z + y
return z
如果你想让函数体内的名字y
和z
引用你的全局变量当你给它们赋值时,你必须声明他们是这样的:
x = 2
y = 3
z=17
def add_nums():
global y
global z
y = 6
z = z + y
return z
否则,当您在函数内部对变量 y
和 z
进行赋值时,您会创建仅存在于函数局部范围内的不同名称。
正如评论中所指出的,您可以引用一个全局变量,如果它是可变的(即向列表中添加一些内容),您甚至可以修改它,只要您不尝试将其分配给它。
我们来分析标记线。
x = 2
y = 3
z = 17
def add_nums():
y = 6
z = z + y <--- THIS LINE
return z
z ...创建了一个新的局部变量
= ...我们要给它赋值
z ... 这个变量存在(新的本地变量)但它还没有值。
+ y ...这部分没到
结果是一条错误消息 "UnboundLocalError: local variable 'z' referenced before assignment"。