What happens is that you are shadowing the class variable with a member variable.
See what happens when you instanciate another myclass-object and add a few printouts to your code:
class myclass(object):
i=0
def increase(self):
myclass.i+=1
print('incresed value:',self.i)
if __name__=='__main__':
m=myclass()
n=myclass()
print("m.i=", m.i)
print("n.i=", n.i)
m.increase()
print("m.i=", m.i)
print("n.i=", n.i)
The output is now:
m.i= 0
n.i= 0
incresed value: 1
m.i= 1
n.i= 0
You see that you incremented the value of the i-member of m, but not of n. This is because self (like this in c++) always refers to the current object instance. If you update your code to the following, you are actually incrementing the class variable:
def increase(self):
myclass.i+=1
print('incresed value:',self.i)
And the output changes to the following:
m.i= 0
n.i= 0
incresed value: 1
m.i= 1
n.i= 1
Like Guillaume Jacquenot already stated in his answer, if you'd like to use member variables, it is advisable to initialize them in __init__(). In your case, the interpreter ist just using the class variable with the same name when it can't find a member variable, and in the same line initializing a member variable (with identical name i). If you comment out the class variable, you're trying to increment a variable which does not exist yet, hence the interpreter error.