The sticky issue to a Python beginner here is that abc
is a class variable (i.e. a "static" variable), and when you do c1.abc = 3
, you shadow the class variable with an instance variable. When you do del c1.abc
the del
applies to the instance variable, so calling c1.abc
now returns the class variable.
The following interactive session should clear some things up:
>>> class C:
... abc = 2
...
>>> c1 = C()
>>> c2 = C()
>>> c1.abc = 3
>>> c1.abc
3
>>> c2.abc
2
>>> C.abc # class "static" variable
2
>>> del c1.abc
>>> c1.abc
2
>>> c2.abc
2
>>> C.abc
2
>>> del c2.abc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: C instance has no attribute 'abc'
>>> del C.abc
>>> c1.abc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: C instance has no attribute 'abc'
>>>
It is del.<someattribute>
always deletes the instance attribute. It won't delete a class-level attribute if applied to an instance, instead, you have to apply it to the class!
In Python, everything written inside a class block is always at the class level. In this sense, it is simpler than Java. To define an instance variable, you need to assign directly to an instance, outisde a method (c1.abc = 3
) or inside a method, using the first parameter passed to that method (by convention this is called self
but could be banana
if you wanted):
>>> class C:
... def some_method(banana, x): # by convention you should use `self` instead of `banana`
... banana.x = x
...
>>> c = C()
>>> c.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: C instance has no attribute 'x'
>>> c.some_method(5)
>>> c.x
5