被python描述符和__get __()混淆

时间:2015-06-29 07:36:01

标签: python descriptor

这是一个简单的类,我只想测试关于__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__()的功能,以及如何使用它。

2 个答案:

答案 0 :(得分:0)

  

为什么des的输出是不同的(一个是1类型(int),一个是对象类型(Des))。

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

在第二种情况下,您在des的实例上查找(属性访问)名称A。属性解析机制(在object.__getattribute__中实现)在des中找到名称A.__dict__并找出关联的对象实现__get__,因此它调用A.__dict__["des"].__get__(a, A)并返回结果 - 在这种情况下A. dict [&#34; des&#34;]。num , which is int(1)`。

  

a.__dict__A.__dict__的输出也不同。

当然可以。 A.__dict__是类A的字典,a.__dict__是实例a的字典。你为什么期望他们分享同一个词?

  

__get__()的功能是什么,以及如何使用它。

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

答案 1 :(得分:0)

在您的代码中 des是一个类属性,在描述符中它(class attr)会调用get(),在接下来的 a.des调用 call()方法所以,这就是你获得不同输出的原因(在你的示例输出中)。