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 .. aswith .. asfor 循环中使用名称作为目标,或者通过创建函数或 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

如果你想让函数体内的名字yz引用你的全局变量当你给它们赋值时,你必须声明他们是这样的:

x = 2 
y = 3 
z=17 
def add_nums(): 
    global y 
    global z 
    y = 6
    z = z + y
    return z

否则,当您在函数内部对变量 yz 进行赋值时,您会创建仅存在于函数局部范围内的不同名称。

正如评论中所指出的,您可以引用一个全局变量,如果它是可变的(即向列表中添加一些内容),您甚至可以修改它,只要您不尝试将其分配给它。

我们来分析标记线。

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"。