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