This is a completely theoretical question. Suppose the following code:
>>> class C:
... a = 10
... def f(self): self.a = 999
...
>>>
>>> C.a
10
>>> c = C()
>>> c.a
10
>>> c.f()
>>> c.a
999
At this point, is class variable C.a still accessible through the object c?
Yes, though c.__class__.a or type(c).a. The two differ slightly in that old-style classes (hopefully, those are all dead by now - but you never know...) have a type() of <type 'instance'> (and __class__ works as expected) while for new-style classes, type() is identical to __class__ except when the object overrides attribute access.
After you assign to it on the class instance, there is both a class attribute named a and an instance attribute named a. I illustrate:
>>> class Foo(object):
... a = 10
...
>>> c = Foo()
>>> c.a
10
>>> c.a = 100 # this doesn't have to be done in a method
>>> c.a # a is now an instance attribute
100
>>> Foo.a # that is shadowing the class attribute
10
>>> del c.a # get rid of the instance attribute
>>> c.a # and you can see the class attribute again
10
>>>
The difference is that one exists as an entry in Foo.__dict__ and the other exists as an entry in c.__dict__. When you access instance.attribute, instance.__dict__['attribute'] is returned if it exists and if not then type(instance).__dict__['attribute'] is checked. Then the superclasses of the class are checked but that gets slightly more complicated.
But at any rate, the main point is that it doesn't have to be one or the other. A class and an instance can both have distinct attributes with identical names because they are stored in two separate dicts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With