我开始自学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是全球可访问的。
答案 0 :(得分:4)
Python通过绑定操作确定范围 。分配是绑定操作,导入时使用名称作为except .. as
,with .. as
或for
循环中的目标,或者通过创建函数或类。
当一个名称绑定在作用域中时,它是该作用域的本地名称。如果使用了名称但未绑定,则为非本地名称;编译器将在编译时确定范围应该是什么。在您的情况下,除了全局范围之外没有父范围,因此任何未绑定的名称都被视为全局。
由于您的第二个示例绑定到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)
如果您希望函数体中的名称y
和z
在向其分配内容时引用全局变量 ,则必须将它们声明为:< / p>
x = 2
y = 3
z=17
def add_nums():
global y
global z
y = 6
z = z + y
return z
否则,当您对函数内的变量y
和z
执行赋值时,您将创建仅存在于函数本地范围内的不同名称。
正如评论中所指出的,你可以引用一个全局变量,甚至可以修改它,如果它是可变的(即将某些内容附加到列表中),只要你没有尝试分配它就不会明确地将其声明为全局变量。
答案 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;。