Python global variable/scope confusion [duplicate]

南楼画角 提交于 2020-04-11 07:37:11

问题


I've started teaching myself python, and have noticed something strange to do with global variables and scope. When I run this:

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

The result of 23 is printed... However, when I expand the return to be:

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

I get the following error on line 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.

I'm confused as why I am getting an error here, as z is global an accessible.


回答1:


When a variable is on the left side of an equal sign python will create a local variable. When the variable is on the right side of the equal sign python will try to look for a local variable and if he can't find one then it will use a global variable. In your example, z is on the right and left side of the equal sign, to avoid ambiguities python raises an error. You need to use the global syntax to avoid this:

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



回答2:


Python determines scope by binding operations. Assignment is a binding operation, as is importing, using a name as a target in except .. as, with .. as or a for loop, or by creating a function or a class.

When a name is bound in a scope, it is local to that scope. If a name is used but not bound, it is non-local; the compiler will determine at compile time what the scope should be then. In your case there is no parent scope other than the global scope, so any name not bound to is considered a global.

Since your second example binds to z (you used z =, an assignment), the name is local to the function.

If a name is bound to in a scope but you want to tell Python that it should be global anyway, you need to do so explicitly:

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

The global z line tells the compiler that z should be a global, even though you bind to it.




回答3:


Let's analyse the marked line.

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

z ... a new local variable is created
= ... we are going to assign a value to it
z ... this variable exists (the new local one) but it has no value yet.
+ y ... this part is not reached.

The result is an error message "UnboundLocalError: local variable 'z' referenced before assignment".




回答4:


If you want the names y and z inside the function body to reference your global variables when you assign something to them, you must declare them like this:

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

Otherwise, when you perform an assignment to the variables y and z inside the function, you create different names that exist only in the local scope of the function.

As pointed out in the comments, you can reference a global variable and even modify it if it is mutable (i.e. append something to a list) without explicitly declaring it global as long as you don't try to assign to it.



来源:https://stackoverflow.com/questions/30439772/python-global-variable-scope-confusion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!