Python描述符 - 文档不清楚

时间:2014-02-05 10:00:57

标签: python namespaces descriptor

我正在查看python的描述符文档here,让我思考的声明是:


对于对象,机制位于object.__getattribute__(),将b.x转换为type(b).__dict__['x'].__get__(b, type(b))


在名为Invoking Descriptors

的部分下

声明b.x into type(b).__dict__['x'].__get__(b, type(b))的最后部分导致此处发生冲突。根据我的理解,如果我们在实例上查找属性,那么正在查找instance.__dict__,如果我们没有找到任何type(instance).__dict__被引用。

在我们的示例中,b.x应该被评估为:

b.__dict__["x"].__get__(b, type(b)) 代替

type(b).__dict__['x'].__get__(b, type(b))

这种理解是否正确?或者我在解释的某个地方出错了? 任何解释都会有所帮助。

感谢。

我也在添加第二部分:

为什么实例属性不遵循描述符协议?例如:参考下面的代码:

>>> class Desc(object):
...     def __get__(self, obj, type):
...         return 1000
...     def __set__(self, obj, value):
...         raise AttributeError
... 
>>> 
>>> class Test(object):
...     def __init__(self,num):
...         self.num = num
...         self.desc = Desc()
... 
>>> 
>>> t = Test(10)
>>> print "Desc details are ", t.desc
Desc details are  <__main__.Desc object at 0x7f746d647890>

感谢您帮助我。

1 个答案:

答案 0 :(得分:1)

您的理解不正确。 x很可能根本没有出现在实例的字典中;描述符对象出现在类的dict或其中一个超类的字典中。

让我们举个例子:

class Foo(object):
    @property
    def x(self):
        return 0

    def y(self):
        return 1

 x = Foo()
 x.__dict__['x'] = 2
 x.__dict__['y'] = 3

Foo.xFoo.y都是描述符。 (属性和函数都实现了描述符协议。)

当我们访问x.x时:

>>> x.x
0

我们没有从x的词汇中获得价值。相反,由于Python在x中找到名为Foo.__dict__的数据描述符,因此调用

Foo.__dict__['x'].__get__(x, Foo)

并返回结果。数据描述符胜过实例dict。

另一方面,如果我们尝试x.y

>>> x.y
3

我们得到3,而不是绑定的方法对象。函数没有__set____delete__,因此实例dict会覆盖它们。


至于你问题的新第2部分,描述符在实例dict中不起作用。考虑如果他们这样做会发生什么:

class Foo(object):
    @property
    def bar(self):
        return 4

Foo.bar = 3

如果描述符在实例dict中起作用,则对Foo.bar的赋值将在Foo的dict中找到描述符并调用Foo.__dict__['bar'].__set__。描述符的__set__方法必须处理在类和实例上设置属性,并且它必须以某种方式区分,即使面对元类。没有令人信服的理由以这种方式使协议复杂化。