I think that there is no exception in the first two lines of the
function because the "Test" and "test" are referenced.
Correct. And they refer to the class attribute var
, not the global one you defined.
The member "var" is assigned, but "Test" and "test" are global because are referenced to get the member.
Or to put it another way, Test
and test
are available in the global namespace so Test.var
and test.var
work.
If the value of var
was not changed in sum()
, you would get 0 since the lines above it have changed the Test
class attribute not the global. Adding some print
s in sum and removing the var += 1
def sum():
Test.var += 1
print Test.var
test.var += 1
print test.var
print var
sum()
...gives:
1
2
0
But the moment I try to assign a value to var within the sum function, I get an error even before that line:
>>> def sum():
... Test.var += 1
... print Test.var
... test.var += 1
... print test.var
... print var
... var += 1
... print var
...
>>> sum()
1
2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in sum
UnboundLocalError: local variable 'var' referenced before assignment
Because var
is now being assigned a value in sum(), it's considered local but has not been defined prior to that line. (Which implies that python is doing some 'looking ahead' or checking variable scope
in sum() since it raised the error for the first print var
before var
was re-assinged. Putting var = 50
instead of var += 1
raises the same error.)
To work with the global var:
def sum():
Test.var += 1
print Test.var
test.var += 1
print test.var
global var #added the global keyword
print var
var += 1
print var
output:
1
2
0 # notice that global var is still 0 because the above var+=1 are for Test.var
1
Edit: Regarding the 'look ahead' behaviour I mentioned. Was going to post a question about it but it's been explained well in this answer: https://stackoverflow.com/a/370380/1431750 (to Python variable scope error)