被 python 描述符和 __get__() 混淆

Confused by python descriptors and __get__()

这是一个简单的 class,我只是想测试有关 __get__() 的功能 代码是:

class Des(object):
    def __init__(self,num):
        self.num = num
    def __get__(self, obj, typ = None):
        return self.num

class A(object):
    des = Des(1)
    print 'the des in class is ',des

a = A()
print  'the des in object is ',a.des
print a.__dict__
print A.__dict__

输出是:

the des in class is  <Des object at 0x7f5fb550ded0>
the des in object is  1
{}
{'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__builtin__', 'des': <Des object at 0x7f5fb550ded0>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}

我的问题是为什么 des 的输出是 des 是不同的(一个是 1 type(int),一个是对象 type(Des))。而且 a.__dict__A.__dict 的输出也不一样。 __get__()有什么作用,如何使用

why the outputs of des are different (one is 1 type(int), one is object type(Des)).

在第一种情况下,您将在 A class 语句的正文中打印 Des 的实例。此时它只是一个普通的 Python 对象——不涉及描述符协议,因为您没有对 class 或实例进行属性访问,因为 A class甚至还不存在 - 所以你得到 Des 对象的默认表示。

在第二种情况下,您正在 A 的实例上查找(属性访问)名称 des。属性解析机制(在object.__getattribute__中实现)在A.__dict__中找到名称des,并找出关联对象实现__get__,因此调用A.__dict__["des"].__get__(a, A)和returns 结果 - 在本例中为 A.dict["des"].num, which isint(1)`.

And the output of a.__dict__ and A.__dict__ is also different.

当然可以。 A.__dict__是class的字典Aa.__dict__是实例a的字典。你为什么期望 same 共享相同的字典?

What's the function of __get__(), and how to use it.

Martijn Pieters 的链接将回答这个问题。

在您的代码中, des 是一个 class 属性,在描述符中它(class attr)将调用 get() ,在下一个 a.des 调用 <strong>call</strong>() 方法,这就是你得到不同输出的原因(在你的示例输出中)。