具有旧式类的Python描述符 [英] Python descriptors with old-style classes

查看:75
本文介绍了具有旧式类的Python描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用Google搜索它。为什么非数据描述符可以与旧式类一起使用?

I tried to google something about it. Why do non-data descriptors work with old-style classes?

医生说他们不应该这样:

请注意,描述符仅针对新样式对象或类(子类 object() type())。

Docs say that they should not:
"Note that descriptors are only invoked for new style objects or classes (ones that subclass object() or type()).".

class Descriptor(object):
    def __init__(self):
        self.x = 1

    def __get__(self, obj, cls=None):
        return self.x


class A:
    x = Descriptor()

a = A()
a.x

>>> 1

谢谢。

推荐答案

您是对文档提出质疑的权利。我尝试浏览 CPython来源来找到解释,但被警告:我没有专家。

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.

据我了解,属性查找和描述符 __ get __ 的调用发生在 instance_getattr2 (选择的摘录):

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).

为了记录,我尝试重新编译Python以将描述符调用限制为新样式类对象,但实际上带来了巨大的混乱。我在该过程中了解到,类方法本身是作为描述符实现的:这是一种根据用法返回绑定或未绑定方法对象的机制。例如:

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>>

结果,似乎阻止了对老式对象或至少在CPython实现中,类也将阻止对它们的方法调用

再次,我不是专家,这是我第一次潜水进入Python实现,所以我很可能会错。我已提交了一个问题,试图澄清这一点。

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.

这篇关于具有旧式类的Python描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆