Python global variable/scope confusion [duplicate] - python

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Using global variables in a function
(25 answers)
Closed 7 years ago.
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.

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

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.

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

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.

Related

python 3 local variable defined in enclosing scope referenced before assignment

I have declared global variables that i need to access and modify in a function in a class. This function loops indefinitely once called and stream data passes through it. I need to be able to use x y z variables inside the function, and redefine their values as stream_data comes through.
My current code looks like this:
x = 10
y = 8
z = 2
class Program():
def function(stream_data):
while True:
try:
a = stream_data['data']
if (a - z) > y:
y = a - z
else:
pass
except:
continue
I get error "local variable y defined in enclosing scope on line 7 referenced before assignment".
How can I format this code so that when the function is first called, it uses the global variables, and then on each subsequent calling it uses the variable y it redefined? Thanks I am new to coding and really need help!
Use
global x, y, z to use the global variables
Like This-
x = 10
y = 8
z = 2
class Program():
def function(stream_data):
while True:
try:
global x,y,z
a = stream_data['data']
if (a - z) > y:
y = a - z
else:
pass
except:
continue
Alternatively, you can also initialize x,y,z within your function.
Let me know if this helps!

Could some explain the following behavior of global variable in python? [duplicate]

This question already has answers here:
In Python what is a global statement?
(5 answers)
Closed 4 years ago.
test.py
x = 10; # global variable
def func1():
print(x); # prints 10
def func2()
x = x + 1; # IDE shows error: "Unresolved reference of x(RHS of expression)
def func3()
global x;
x = x + 1; # This works
When x has a global scope, why doesn't func2() allow me to modify its value though it is accessible as seen in func1(). And why does it require explicit mention of "global" keyword as in case of func3() ?
You can access global variables but for modifying them it should be explicitly declared that variable is a global variable.
I think this link would be useful.
The reason behind it is that when you say x = x + 1, python thinks that you want a local variable x and then when reaches the x + 1 expression python finds out that the local variable x was mentioned but not assigned any value so it gets confused.

Using a variable from a different subprogram [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 8 years ago.
I need to create program code in python that uses a defined variable from a different subprogram using a simple version:
x = 'ham'
def a():
x = 'cheese'
def b():
print(x)
a()
b()
How do I get this to save the global variable x as cheese instead of ham?
Whenever you mutate a global variable in a function, you have to explicitly declare that you're using it as a global:
x = 1
def a():
global x
x = 4
def b():
print(x)
a()
b()
Otherwise, a just creates a local variable x that shadows the global.
I'm guessing by subprogram you mean function?
The reason you are getting a 1 instead of a 4 is because x = 1 sets a global variable (in the global scope).
When you do x = 4 inside of a function it creates a local variable (in that function's local scope). Once the function is finished, the local variables are discarded.
When you call b() and it tries to look up the value of x, there is no local variable x (in b's local scope) so it uses the global variable x, which is 1.
If you want a() to modify the global variable x, you have to options:
1) You can just modify the global variable explicitly
def a():
global x
x = 4
2) You can return the local varaible and assign it to the global (preferred)
def a():
x = 4
return x
x = a()

python : local variable is referenced before assignment [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 8 years ago.
Here is my code :
x = 1
def poi(y):
# insert line here
def main():
print poi(1)
if __name__ == "__main__":
main()
If following 4 lines are placed, one at a time, in place of # insert line here
Lines | Output
---------------+--------------
1. return x | 1
2. x = 99 |
return x | 99
3. return x+y | 2
4. x = 99 | 99
In above lines it seems that global x declared above function is being used in case 1 and 3
But ,
x = x*y
return x
This gives
error : local variable 'x' is reference before assignment
What is wrong in here ?
When Python sees that you are assigning to x it forces it to be a local variable name. Now it becomes impossible to see the global x in that function (unless you use the global keyword)
So
Case 1) Since there is no local x, you get the global
Case 2) You are assigning to a local x so all references to x in the function will be the local one
Case 3) No problem, it's using the global x again
Case 4) Same as case 2
When you want to access a global variable, you can just access it by its name. But if you want to change its value, you need to use the keyword global.
try :
global x
x = x * y
return x
In case 2, x is created as a local variable, the global x is never used.
>>> x = 12
>>> def poi():
... x = 99
... return x
...
>>> poi()
99
>>> x
12

python global variable, whats going on here? Explanation needed

Can someone explain what's going on here
x = 10
def foo():
print "x in foo = ",x
if x: x = 8 -------------> mysterious line
foo()
print "x in main = ",x
In the above code, If i comment out the mysterious line (if x: x = 8)
I get the output
x in foo = 10
x in main = 10
Otherwise I end up with error
"UnboundLocalError: local variable 'x' referenced before assignment"
Why so?
I know global x is helpful only when I need to modify a global variable locally.
As soon as you make an assignment to x anywhere in the function, it becomes a local variable, even if there are references to its value prior to the assignment.
In your function, you assign to x with no global declaration, so x is a local variable. However, you attempt to read x in the function before it's assigned to, so you have an unbound local at that point.
What may seem strange at first is that local names are detected statically: if the name x is assigned anywhere in the function, Python assumes that x is a local name everywhere in the function.
In other words, the line order in your function is misleading: as long as x is assigned somewhere in the function, the first line's x becomes a reference to a local variable (which at this code point is still unbound).
Like Wooble already said, you need to declare the modifikation of a global variable before usage.
def foo():
global x
print "x in foo = ",x
if x: x = 8
x = 8 anywhere in the function without global x makes it a local variable. print x fails because a local variable is not initialized

Categories

Resources