Python: Metaclass properties override class attributes, sometimes?

metaclass, python

Solution

Properties are data descriptors; in attribute lookups, they take priority over identically-named entries in the dict of an instance of the class with the property. That means that with

MyObject.a

the `a` property in `MyClass` takes priority over the `a` entry in `MyObject`'s dict. Similarly,

object.__getattribute__(MyObject, 'a')
type.__getattribute__(MyObject, 'a')

`object.__getattribute__` and `type.__getattribute__` both respect the priority of data descriptors over instance dict entries, so the property wins.

On the other hand,

MyObject.__dict__['a']

this explicitly does a dict lookup. It only sees things in `MyObject`'s dict, ignoring the normal attribute lookup mechanisms.

For the last line:

MyObject().a

the `MyClass` descriptor only applies to instances of `MyClass`, not instances of its instances. The attribute lookup mechanism doesn't see the property.

Problem

The result of the below code boggles me: ``` class MyClass(type): @property def a(self): return 1 class MyObject(object): __metaclass__ = MyClass a = 2 print MyObject.a print object.__getattribute__(MyObject, 'a') print type.__getattribute__(MyObject, 'a') print MyObject.__dict__['a'] print MyObject().a ``` I really expect this to just print `2` repeatedly, but it prints `1 1 1 2 2`. Is there a way this makes any intuitive sense? To clarify: I understand that this behavior is well documented (here, "data descriptors"), but I want to have an understanding of why this makes sense, and why the core devs implemented descriptors this way.

Original source

Related problems