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.
Related
This question already has answers here:
Variables declared outside function
(3 answers)
Closed 3 months ago.
This post was edited and submitted for review 3 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I encounter no problems running this code:
x = 1
def func():
print(x + 1)
func()
2
But when I run this:
x = 1
def func():
try:
x += 1
except:
pass
print(x + 1)
func()
An error pops:
UnboundLocalError: cannot access local variable 'x' where it is not associated with a value
I am not asking if I can modify global variables in functions or not. I used try-except keywords to avoid that error. After python caught the exception, I thought nothing would change and print(x + 1) would work like the first code. So what changed in the scope during the try-except part that x is no longer accessible?
The first example works because the function does not assign to the x variable; it only reads the variable.
The second example fails because if a function assigns to a variable then it is assumed to be a local variable, even if there is a global variable of the same name.
If you want to use the global variable in the function, put global x at the top of the function.
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:
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.
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:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 6 years ago.
Why does this not work in python?, where I can access the enclosing scope (here global scope) when there are no other references to the same variable but can't when there are.
Does the interpreter look further down the function first before for the variable definition, finds it so assumes it is only a local variable which hasn't yet been assigned a value? What's the run order of the interpreter here?
> a = 5
> a
Out[3]:
5
> def closure():
print(a)
> closure()
5
> def closure():
print(a)
a = "another"
return a
> closure()
UnboundLocalError: local variable 'a' referenced before assignment
Add global a to the first line of the function.