Python global variable/scope confusion
我开始自学python,并注意到一些与全局变量和范围有关的奇怪事情。当我运行这个时:
1 2 3 4 5 6 | x = 2 y = 3 z=17 def add_nums(): y = 6 return z+y |
23的结果打印出来…但是,当我将回报率扩展为:
1 2 3 4 5 6 7 | x = 2 y = 3 z=17 def add_nums(): y = 6 z = z + y return z |
我在第6行得到以下错误:
1 2 3 | 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将创建一个局部变量。当变量位于等号的右侧时,python将尝试查找局部变量,如果找不到局部变量,则它将使用全局变量。在您的示例中,z位于等号的左右两侧,为了避免含糊不清,python会引发一个错误。您需要使用
1 2 3 4 5 6 7 8 | x = 2 y = 3 z=17 def add_nums(): global z y = 6 z = z + y return z |
python通过绑定操作确定作用域。赋值是一个绑定操作,和导入一样,在
当名称绑定到作用域中时,它是该作用域的本地名称。如果一个名称被使用但没有被绑定,那么它是非本地的;编译器将在编译时确定该范围应该是什么。在您的情况下,除了全局作用域之外没有父作用域,因此任何未绑定到的名称都被视为全局名称。
由于第二个示例绑定到
如果名称在作用域中绑定到,但您希望告诉python它应该是全局的,则需要显式地这样做:
1 2 3 4 5 6 7 8 | x = 2 y = 3 z=17 def add_nums(): global z y = 6 z = z + y return z |
让我们分析一下标记线。
1 2 3 4 5 6 7 | 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"。
如果您希望函数体中的名称
1 2 3 4 5 6 7 8 9 | x = 2 y = 3 z=17 def add_nums(): global y global z y = 6 z = z + y return z |
否则,当您在函数内对变量
正如注释中指出的,如果全局变量是可变的(即在列表中附加一些内容),则可以引用它,甚至可以对其进行修改,而不必显式地将其声明为全局变量,只要不尝试为其赋值。