Python descriptors with old-style classes

感情迁移 提交于 2019-12-05 08:00:21

You are right to question the documentation. I've tried looking through CPython sources to find an explanation, but be warned: I'm no expert.

From my understanding, attribute lookup and descriptor __get__ invocation occurs in instance_getattr2 (chosen extracts):

v = class_lookup(inst->in_class, name, &klass);
if (v != NULL) {
    f = TP_DESCR_GET(v->ob_type);
    if (f != NULL) {
        PyObject *w = f(v, (PyObject *)inst, (PyObject *)(inst->in_class));
    }
}

So either I am missing something, or nothing in the implementation requires a new-style object (which contradicts the documentation).

For the record, I tried recompiling Python to restrict descriptor invocation to new style classes objects, but it actually brought up a gigantic mess. I learned in the process that class methods themselves are implemented as descriptors: this is the mechanism used to return bound or unbound method objects depending on the usage. For example:

>>> class A:
...     def foo():
...         pass
...
>>> A.foo.__get__(None, A)
<unbound method A.foo>
>>> A.foo.__get__(A(), A)
<bound method A.foo of <__main__.A instance at 0x000000000229CC48>>

As a result, it seems that preventing descriptor invocation for attributes of old-style objects or classes would also prevent method calls on them, at least with CPython implementation.

Once again, I'm no expert and this is the first time I dive into Python implementation, so I could very well be wrong. I've filed an issue to try to clarify this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!