0

I'm new to Python and saw this code snippet:

class C:
    abc = 2

c1 = C()
print c1.abc

c1.abc = 3
print c1.abc

del c1.abc
print c1.abc

I understand why the first and the second print statements print 2, respectively 3. Coming from a Java background however, I don't understand what happens in the line 'del c1.abc' and why the last print statement prints 2 and not some kind of an error. Can someone explain? If possible by comparing to Java?

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
user6189
  • 653
  • 1
  • 7
  • 15
  • @Aaron I don't understand how this is even slightly related to my question. Can you elaborate? – user6189 Apr 10 '17 at 18:52
  • 2
    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. – juanpa.arrivillaga Apr 10 '17 at 18:52
  • @Aaron but that isn't what's going on here. – juanpa.arrivillaga Apr 10 '17 at 18:54
  • @juanpa.arrivillaga Tha's exactly the answer I was looking for! Thanks! Can you copy that to an actual answer? Then I could upvote and accept :) – user6189 Apr 10 '17 at 18:54
  • @juanpa.arrivillaga true, I'll remove my comment.. yours is much more relevant – Aaron Apr 10 '17 at 18:54
  • So, do the same thing as above, but create a new instance `c = C()`. Now try `del c.abc` and you'll get an error. – juanpa.arrivillaga Apr 10 '17 at 18:54
  • @juanpa.arrivillaga: Bad dupe. It doesn't say anything about the interaction of `del` and object attributes; it's all about memory management and ordinary variables. – user2357112 Apr 10 '17 at 18:55
  • @Aaron this is a duplicate, one way or another, so I'd rather just let it be dupe-targetd. – juanpa.arrivillaga Apr 10 '17 at 18:55
  • @user6189 it's sort of a combination of that one and [this](http://stackoverflow.com/questions/5690888/variable-scopes-in-python-classes) one. Perhaps a gold-tagger coudl add the second target too. – juanpa.arrivillaga Apr 10 '17 at 18:57
  • Fine, I guess I'll just post my comment as an answer if y'all don't think this is a duplicate. – juanpa.arrivillaga Apr 10 '17 at 18:57

1 Answers1

3

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
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • Thanks a lot! This clears many things up! – user6189 Apr 10 '17 at 19:03
  • @user6189 I added a little bit about class-level variables in Python. It is helpful to read through the [official tutorial](https://docs.python.org/3/tutorial/classes.html). Python class definitions are really simple, but they work a little differently than a Java class definition. – juanpa.arrivillaga Apr 10 '17 at 19:06