class attribute lookup rule?
<pre><code>&gt;&gt;&gt; class D:
...     __class__ = 1
...     __name__ = 2
...
&gt;&gt;&gt; D.__class__
&lt;class 'type'&gt;
&gt;&gt;&gt; D().__class__
1
&gt;&gt;&gt; D.__name__
'D'
&gt;&gt;&gt; D().__name__
2
</code></pre>

<p><strong>Why does <code>D.__class__</code> return the name of the class, while <code>D().__class__</code> returns the defined attribute in class D?</strong> </p>

<p><strong>And from where do builtin attributes such as <code>__class__</code> and <code>__name__</code> come from?</strong> </p>

<p>I suspected <code>__name__</code> or <code>__class__</code> to be simple descriptors that live either in <code>object</code> class or somewhere, but this can't be seen.</p>

<p>In my understanding, the attribute lookup rule as follows in Python, omitting the conditions for descriptors etc..: </p>

<p><code>Instance --&gt; Class --&gt; Class.__bases__ and the bases of the other classes as well</code></p>

<p>Given the fact that a class is an instance of a metaclass, <code>type</code> in this case, why <code>D.__class__</code> doesn't look for <code>__class__</code> in <code>D.__dict__</code>?</p>

<p>The names <code>__class__</code> and <code>__name__</code> are special. Both are <em>data descriptors</em>. <code>__name__</code> is defined on the <code>type</code> object, <code>__class__</code> is defined on <code>object</code> (a base-class of all new-style classes):</p>

<pre><code>&gt;&gt;&gt; type.__dict__['__name__']
&lt;attribute '__name__' of 'type' objects&gt;
&gt;&gt;&gt; type.__dict__['__name__'].__get__
&lt;method-wrapper '__get__' of getset_descriptor object at 0x1059ea870&gt;
&gt;&gt;&gt; type.__dict__['__name__'].__set__
&lt;method-wrapper '__set__' of getset_descriptor object at 0x1059ea870&gt;
&gt;&gt;&gt; object.__dict__['__class__']
&lt;attribute '__class__' of 'object' objects&gt;
&gt;&gt;&gt; object.__dict__['__class__'].__get__
&lt;method-wrapper '__get__' of getset_descriptor object at 0x1059ea2d0&gt;
&gt;&gt;&gt; object.__dict__['__class__'].__set__
&lt;method-wrapper '__set__' of getset_descriptor object at 0x1059ea2d0&gt;
</code></pre>

<p>Because they are data descriptors, the <a href="https://docs.python.org/3/reference/datamodel.html#object.__getattribute__" rel="nofollow"><code>type.__getattribute__</code> method</a> (used for attribute access on a class) will ignore any attributes set in the class <code>__dict__</code> and only use the descriptors themselves:</p>

<pre><code>&gt;&gt;&gt; type.__getattribute__(Foo, '__class__')
&lt;class 'type'&gt;
&gt;&gt;&gt; type.__getattribute__(Foo, '__name__')
'Foo'
</code></pre>

<p>Fun fact: <code>type</code> derives from <code>object</code> (<em>everything</em> in Python is an object) which is why <code>__class__</code> is found on <code>type</code> when checking for data descriptors:</p>

<pre><code>&gt;&gt;&gt; type.__mro__
(&lt;class 'type'&gt;, &lt;class 'object'&gt;)
</code></pre>

<p>(<code>type.__getattribute__(D, ...)</code> is used directly as an unbound method, not <code>D.__getattribute__()</code>, because <a href="https://docs.python.org/3/reference/datamodel.html#special-lookup" rel="nofollow">all special method access goes to the type</a>).</p>

<p>See the <a href="https://docs.python.org/3/howto/descriptor.html" rel="nofollow"><em>Descriptor Howto</em></a> an what constitutes a data descriptor and why that matters:</p>

<blockquote>
  <p>If an object defines both <code>__get__()</code> and <code>__set__()</code>, it is considered a data descriptor. Descriptors that only define <code>__get__()</code> are called non-data descriptors (they are typically used for methods but other uses are possible).</p>
  
  <p>Data and non-data descriptors differ in how overrides are calculated with respect to entries in an instanceâs dictionary. If an instanceâs dictionary has an entry with the same name as a data descriptor, the data descriptor takes precedence. If an instanceâs dictionary has an entry with the same name as a non-data descriptor, the dictionary entry takes precedence.</p>
</blockquote>

<p>For data descriptors on <code>type</code>, a class is just another instance.</p>

<p>So when looking up the <code>__class__</code> or <code>__name__</code> attributes, it doesn't matter what is defined in the <code>D.__dict__</code> namespace, because for either a data descriptor is found in the namespace formed by <code>type</code> and it's MRO.</p>

<p>These descriptors are defined in the <a href="https://hg.python.org/cpython/file/v3.5.1/Objects/typeobject.c" rel="nofollow"><code>typeobject.c</code> C code</a>:</p>

<pre class="lang-c prettyprint-override"><code>static PyGetSetDef type_getsets[] = {
    {"__name__", (getter)type_name, (setter)type_set_name, NULL},
    /* ... several more ... */
}

/* ... */

PyTypeObject PyType_Type = {
    PyVarObject_HEAD_INIT(&amp;PyType_Type, 0)
    "type",                                     /* tp_name */
    /* ... many type definition entries ... */
    type_getsets,                               /* tp_getset */
    /* ... many type definition entries ... */
}

/* ... */

static PyGetSetDef object_getsets[] = {
    {"__class__", object_get_class, object_set_class,
     PyDoc_STR("the object's class")},
    {0}
};

PyTypeObject PyBaseObject_Type = {
    PyVarObject_HEAD_INIT(&amp;PyType_Type, 0)
    "object",                                   /* tp_name */
    /* ... many type definition entries ... */
    object_getsets,                             /* tp_getset */
    /* ... many type definition entries ... */
}
</code></pre>

<p>On instances, <code>object.__getattribute__</code> is used, and it'll find the <code>__name__</code> and <code>__class__</code> entries in the <code>D.__dict__</code> mapping before it'll find the data descriptors on <code>object</code> or <code>type</code>.</p>

<p>If you omit either, however, then looking up the names on <code>D()</code> will only <code>__class__</code> as a data descriptor in the MRO of <code>D</code> (so, on <code>object</code>). <code>__name__</code> is not found as the metatypes are not considered when resolving instance attributes.</p>

<p>As such you can set <code>__name__</code> on an instance, but not <code>__class__</code>:</p>

<pre><code>&gt;&gt;&gt; class E: pass
...
&gt;&gt;&gt; e = E()
&gt;&gt;&gt; e.__class__
&lt;class '__main__.E'&gt;
&gt;&gt;&gt; e.__name__
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
AttributeError: 'E' object has no attribute '__name__'
&gt;&gt;&gt; e.__dict__['__class__'] = 'ignored'
&gt;&gt;&gt; e.__class__
&lt;class '__main__.E'&gt;
&gt;&gt;&gt; e.__name__ = 'this just works'
&gt;&gt;&gt; e.__name__
'this just works'
</code></pre>

python python-internals