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 -- https://mail.python.org/mailman/listinfo/python-list