This question already has answers here:
Another UnboundLocalError in Python2.7 [duplicate]
(2 answers)
Closed 3 years ago.
What's the difference between doing:
m={}
i='a'
def change():
m['a'] = i
i = 'b'
Which raises an attribute error:
>>> change()
UnboundLocalError: local variable 'i' referenced before assignment
And:
m={}
i='a'
def change():
m['a'] = i
Which evaluates without an error.
>>> change()
>>> m
{'a': 'a'}
(Finally, a question about this question -- when is it appropriate to use the "yellow background" in the questions?)
This is answered in depth in the docs:
This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to x, the compiler recognizes it as a local variable. Consequently when the earlier print(x) attempts to print the uninitialized local variable and an error results.
And the yellow background is stylistic but is generally used for quotes from somewhere but also can be used for any reason you want to break that text away from the main body or text or code.
Related
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 5 months ago.
I am a novice in Python and wondering the situation below.
x = 1
def func():
print(x)
x = 2
return x
So I got the UnboundLocalError: local variable 'x' referenced before assignment.
But if I right understand - Python read and execute code row by row.
So in first statement inside function "print(x)" it must just relay global variable x which eq. 1, but instead I got the error.
Please explain, I think it simple.
I think your problem was explained as well in the FAQ of python docs
This is because when you make an assignment to a variable in a scope,
that variable becomes local to that scope and shadows any similarly
named variable in the outer scope. Since the last statement in foo
assigns a new value to x, the compiler recognizes it as a local
variable. Consequently when the earlier print(x) attempts to print the
uninitialized local variable and an error results.
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)
Local variable referenced before assignment? [duplicate]
(5 answers)
Closed 11 months ago.
def f():
print(x)
def g():
print(x)
x = 1
x = 3
f()
x = 3
g()
It prints 3 when f is invoked, but the error message
UnboundLocalError: local variable 'x' referenced before assignment
is printed when the print statement in g is encountered. This happens because
the assignment statement following the print statement causes x to be local to g.
And because x is local to g, it has no value when the print statement is executed.
The above quote and code are from 《Introduction to Computation and Programming Using Python》
And here is my understanding through this explanation. Just wondering if this is valid:
The print statement in function f does not produce an error because it does not contain the name of x as a local variable, forcing the interpreter to search the stack frame with scope outside the definition of x and finding out that x binds to 3. Then use the value. While, in function g, there exists a local variable binds to number 1 after the print statement, the function already takes x as a local variable as x binds to some values in the function body. The interpreter does not search back to other stack frames with scope, hence the outer x bound will not be searched and used. Based on this, it has no value in x yet when the print statement is executed.
This question already has answers here:
Function not changing global variable
(4 answers)
Closed 5 years ago.
How does the code below give the output as None?
def funct(x):
x=7
x=11
x=test(x)
print(x)
Here is another code snippet:-
def func():
print (x)
x = 90
x = 1
func()
The output for this should be 90! The scope is searched as Local ,Enclosed , Global ,Build-in .Either x should here be searched as local or global
Please explain.
x here is not a global variable in the scope of the functions, as functions naturally create their own namespaces, which do not include any outer variables not passed in as a parameter.
There are many issues with your code, including the order of function calling, and the order of the operations inside the functions; but to answer your question in the broadest way possible, in order for you to access the x variable defined outside of your functions, in a greater scope that is, you need to reference its namespace, by prepending global x inside the body of each of your functions.
Read up on Python variables and scope, and recheck the other errors in your code I have stated above.
The first code snippet returns None for the simple fact that you didn't return any value from the function. You defined x as a local parameter, not a global variable. Since you didn't return any value, your call test(x) (which does not match the function name of funct), will become a value of None. This is clearly defined in the Python documentation. To get the local value back to your main program, try this:
test(x):
x = 7
return x
x = 11
x = test(x)
print(x)
Also, please note that your initial value of 11 is entirely ignored in the main program, and that your function ignores the value it's given. You should shorten this example to
func():
return 7
print(func())
Your second example will print the external value of 1 because you have not defined a local variable x at that point, and a function is allowed to reference global variables.
However, when you assign a value in the next, you create a local variable -- you have not declared x to be global, so you can't assign to the x in the main program.
Again, you do not return any value. Therefore, back in the main program, func() evaluates to None.
Does that clear up what happened?
This question already has answers here:
python: How do I capture a variable declared in a non global ancestral outer scope?
(5 answers)
Closed 8 years ago.
I have a function nested inside an other function. I want to change a variable inside the first function from the nested one.
def myfunc():
step=0
def increment():
step+=1
increment()
increment()
increment()
print("Steps so far:", step)
myfunc()
Gives
UnboundLocalError: local variable 'step' referenced before assignment
If I try and use global, it won't work either since it tries to dereference to a variable step outside myfunc which doesn't exist.
Is there a way to do this without having a global variable?
Declare step as a nonlocal variable. It will make the identifier refer the variable in enclosing scope.
def increment():
nonlocal step
step += 1
NOTE Python 3.x only.
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 9 years ago.
I'm trying to do something along the following lines in python3:
i = 1337
def g():
print(i)
i = 42
g()
but get the following error
UnboundLocalError: local variable 'i' referenced before assignment
I think I understand what the error message means, but why is it the case? Is there any way to circumvent this?
In two words - when a given variable name is not assigned a value within a function then references to the variable will be looked up. Use global - and in such a case python will look for i in global scope:
i = 1337
def g():
global i
print i
i = 42
g()
You can read more on variable scopes in PEP-0227
If you really really want to do it that way, you'll need to get i from the global scope.
def g():
global i
print i
i = 42
However, generally you would be much better off changing how your code works to not require globals. Depending on how you are using it, that could be as simple as passing in i as a parameter and returning the changed value.
An example of Keeyai's suggestion of passing in i as a parameter:
i = 1337
def g(i):
print(i)
i = 42
g(i)
However, you never use the new value of i, so perhaps something like this makes more sense:
def g (i):
i = 42
return i
i = 1337
print g(i)