具有旧式类的Python描述符 [英] Python descriptors with old-style classes
问题描述
我试图用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屋!