Python全局变量/范围混乱

时间:2015-05-25 13:41:15

标签: python scope global-variables jes

我开始自学python,并注意到与全局变量和范围有关的奇怪之处。 当我运行时:

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

打印出23的结果...... 但是,当我将回报扩展为:

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是全球可访问的。

4 个答案:

答案 0 :(得分:4)

Python通过绑定操作确定范围 。分配是绑定操作,导入时使用名称作为except .. aswith .. asfor循环中的目标,或者通过创建函数或类。

当一个名称绑定在作用域中时,它是该作用域的本地名称。如果使用了名称但未绑定,则为非本地名称;编译器将在编译时确定范围应该是什么。在您的情况下,除了全局范围之外没有父范围,因此任何未绑定的名称都被视为全局。

由于您的第二个示例绑定到z(您使用了z =,一个赋值),因此该名称是函数的本地名称。

如果某个名称绑定在作用域中,但您想告诉Python它应该是全局的,那么您需要明确地这样做:

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

global z行告诉编译器z应该是全局的,即使你绑定它

答案 1 :(得分:4)

当变量位于等号的左侧时,python将创建一个局部变量。当变量位于等号的右侧时,python将尝试查找局部变量,如果找不到,那么它将使用全局变量。在你的例子中,z位于等号的右侧和左侧,以避免歧义python引发错误。您需要使用global语法来避免这种情况:

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

答案 2 :(得分:1)

如果您希望函数体中的名称yz在向其分配内容时引用全局变量 ,则必须将它们声明为:< / p>

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

否则,当您对函数内的变量yz执行赋值时,您将创建仅存在于函数本地范围内的不同名称。

正如评论中所指出的,你可以引用一个全局变量,甚至可以修改它,如果它是可变的(即将某些内容附加到列表中),只要你没有尝试分配它就不会明确地将其声明为全局变量。

答案 3 :(得分:1)

让我们分析标记线。

x = 2
y = 3 
z = 17 
def add_nums(): 
    y = 6 
    z = z + y  <--- THIS LINE
    return z

z ...创建一个新的局部变量
= ...我们要给它分配一个值
z ...这个变量存在(新的本地变量),但它还没有价值 + y ......这部分未到达。

结果是错误消息&#34; UnboundLocalError:local variable&#39; z&#39;在分配之前引用&#34;。