python : local variable is referenced before assignment [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)
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

Related

How can I manage the scope problem in Python [duplicate]

This question already has answers here:
Python function global variables? [duplicate]
(6 answers)
Closed last year.
I have the following code:
x = 1
def increaseX(number):
x += number
increaseX(2)
print(x)
I want to increase a glob variable via the function increaseX, what is the best way to do this?
global keyword is what you need:
x = 1
def increaseX(number):
global x
x += number
increaseX(2)
print(x)
Otherwise, Python tries to find x in local namespace because of += (something like x = x + number) and because in the right hand side of the assignment there is no x defined, you will get :
UnboundLocalError: local variable 'x' referenced before assignment
I tried this and it works, but I don't feel this is the best way
x = 1
def increaseX(number):
global x
x += number
increaseX(2)
print(x)

Any type of scope resolution operator in Python?

Is there any way to make the python interpreter choose the global variable specifically when there is also a local variable with the same name? (Like C++ has :: operator)
x=50
def fun():
x=20
print("The value of local x is",x)
global x
#How can I display the value of global x here?
print("The value of global x is",x)
print("The value of global x is",x)
fun()
The second print statement inside the function block should display the value of global x.
File "/home/karthik/PycharmProjects/helloworld/scope.py", line 7
global x
^
SyntaxError: name 'x' is used prior to global declaration
Process finished with exit code 1
Python does not have a direct equivalent to the :: operator (typically that kind of thing is handled by the dot .). To access a variable from an outer scope, assign it to a different name as to not shadow it:
x = 50
def fun():
x = 20
print(x) # 20
print(x_) # 50
print(x) # 50
x_ = x
fun()
But of course Python would not be Python if there weren't a hack around this... What you describe is actually possible, but I do not recommend it:
x = 50
def fun():
x = 20
print(x) # 20
print(globals()['x']) # 50
print(x) # 50
fun()
I don't know any way to do this (and I am not an expert). The two solutions that I can think of are to give another name to your local x (like xLoc), or to put your global x in argument, like this :
x=50
def fun(xGlob):
x=20
print("The value of local x is",x)
print("The value of global x is",xGlob)
print("The value of global x is",x)
fun(x)
Is this answering your question ?

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.

Python global variable/scope confusion [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)
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.

How should I code a function to turn a parameter I input into 1? [duplicate]

This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 8 years ago.
I am the new to Python. Here is a problem that I have encountered.
Assume that there is a function called set1(x).
Here is the code:
def set1(x):
x = 1;
When I run this,
m = 5
set1(m)
m
the value of m is still 5.
So how should I code the function if I want the parameter to become 1 whenever I call the set1() function?
You can return the value
def set1():
return 1;
And call it as
m=5
m = set1()
print (m)
It will print 1
Another way but bad method is to make it global
def set1():
global m
m = 1
Functions use a local namespace in which they declare their variables, which means that in most cases when you pass an argument to a function, it will not effect the argument outside of the function (in the global namespace). So while the value changes within the function, it does not change outside of the function.
If you want the function to change the value, you need to return the value as such:
def set1(x):
x=1
return x
>>> m=5
>>> m = set1(m)
>>> m
1
This said, if your argument is mutable, it can change.
def set2(x):
x[0] = 1
>>> m = [2]
>>> set2(m)
>>> m[0]
1

Categories

Resources