21đ
No, for the same reason as this:
>>> class Foo(object):
... bar = 'Foo attribute'
...
>>> f = Foo()
>>> f.bar
'Foo attribute'
>>> Foo.bar
'Foo attribute'
>>> f.bar = 'instance attribute'
>>> f.bar
'instance attribute'
>>> Foo.bar
'Foo attribute'
When you assign an attribute to an object, a class attribute of the same name will be âeclipsedâ by the objectâs. On attribute lookup, however, if the object in question does not define said attribute, the class one will be returned, instead.
In Django, those class attributes are used by the ORM layer to generate the mechanism that translates to SQL queries and operations (deep, metaclass magic going on behind-the-scenes).
edit: To answer your questionâ
To understand that, you need to understand a little bit about Pythonâs data model. Essentially, both classes and objects have namespaces. This is apparent if you peek into their special __dict__
attribute:
>>> print Foo.__dict__
{'__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute
'__weakref__' of 'Foo' objects>, '__module__': '__main__', 'bar': 'Foo attribute
', '__doc__': None}
>>> f = Foo()
>>> print f.__dict__
{}
When the object f
is first created, it has an empty namespace. When you do a lookup, f.bar
, this namespace (really, a dictionary) is looked up. Since there is no 'bar'
attribute found there, f
âs class, Foo
, is looked up. We find 'bar': 'Foo attribute'
there. So thatâs whatâs going to be returned:
>>> f.bar
'Foo attribute'
Now, when you assign an attribute value to an object, and said attribute name does not yet exist in its namespace, it is created:
>>> f.bar = 'instance attribute'
>>> print f.__dict__
{'bar': 'instance attribute'}
>>> f.bar
'instance attribute'
Now, you know what happens the next time f.bar
is looked up! f.__dict__['bar']
exists and will be returned before we even look at Foo
âs namespace.
Of course, if your intent is to always access and manipulate a classâ attribute instead of the instanceâs, youâd need to use the classâ name.
>>> Foo.bar
'Foo attribute'
>>> Foo.__dict__['bar']
'Foo attribute'