The class itself is an object. You can modify the properties of a class. Every instance derived afterwards inherits these modifications, or to be more correct (see comment of jsbueno) every instance-"variable"/identifier referencing the original object hast instantly the same value.
x and y are not instance-variables but class-variables. So ever invocation/instantiation of the Class modifies them in __init__
.
To get real instance-variables you need them to define inside of the __init__
method.
The slightly different behaviour of x and y are results of the differet mutability of those variables. While the list identified by x is a mutable object, the number 0 isn't! Therefore while with append you also change the state of the object referenced by the class-variable this doesn't happen for y, because y is immutable. Instead you assign a new object to the (now) instance-identifier y
.
That's also the reason, why it's not very accurate to speak of variables in python, but better of "identifier". You practically put a tag/stamp/name-shield on an object. But the coupling between identifier and referenced object is quite loose. You can reattach the tag as you want, without loosing the referenced object, if it's otherwise referenced.