Why do data descriptors (e.g. properties) take priority over instance attributes?
Paul Baker
paulbaker8 at gmail.com
Mon Dec 17 05:57:22 EST 2018
When Python looks up an attribute on an object (i.e. when it executes
`o.a`), it uses an interesting priority order [1]. It looks for:
1. A class attribute that is a data-descriptor (most commonly a property)
2. An instance attribute
3. Any other class attribute
We can confirm this using the code below, which creates an object `o`
with an instance attribute `a`, whose class contains a property of the
same name:
class C:
def __init__(self):
self.__dict__['a'] = 1
@property
def a(self):
return 2
o = C()
print(o.a) # Prints 2
Why does Python use this priority order rather than the "naive" order
(instance attributes take priority over all class attributes, as used
by JavaScript)? Python's priority order has a significant drawback: it
makes attribute lookups slower, because instead of just returning an
attribute of `o` if it exists (a common case), Python must first
search `o`'s class *and all its superclasses* for a data-descriptor.
What is the benefit of Python's priority order? It's presumably not
just for the above situation, because having an instance variable and
a property of the same name is very much a corner case (note the need
to use `self.__dict__['a'] = 1` to create the instance attribute,
because the usual `self.a = 1` would invoke the property).
Is there a different situation in which the "naive" lookup order would
cause a problem?
[1] https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/#object-attribute-lookup
More information about the Python-list
mailing list