If I run the following code:
x = 1
class Incr:
print(x)
x = x + 1
print(x)
print(x)
It prints:
1
2
1
Okay no problems, that's exactly what I expected. And if I do the following:
x = 1
class Incr:
global x
print(x)
x = x + 1
print(x)
print(x)
It prints:
1
2
2
Also what I expected. No problems there.
Now if I start making an increment function as follows:
x = 1
def incr():
print(x)
incr()
It prints 1 just as I expected. I assume it does this because it cannot find x
in its local scope, so it searches its enclosing scope and finds x
there. So far no problems.
Now if I do:
x = 1
def incr():
print(x)
x = x + 1
incr()
This gives me the following error in the traceback:
UnboundLocalError: local variable 'x' referenced before assignment.
Why does Python not just search the enclosing space for x
when it cannot find a value of x
to use for the assignment like my class Incr
did? Note that I am not asking how to make this function work. I know the function will work if I do the following:
x = 1
def incr():
global x
print(x)
x = x + 1
print(x)
incr()
This will correctly print:
1
2
just as I expect. All I am asking is why it doesn't just pull x
from the enclosing scope when the keyword global
is not present just like it did for my class above. Why does the interpreter feel the need to report this as an UnboundLocalError
when clearly it knows that some x
exists. Since the function was able to read the value at x
for printing, I know that it has x
as part of its enclosing scope...so why does this not work just like the class example?
Why is using the value of x
for print so different from using its value for assignment? I just don't get it.