python 描述器,及property 的实现


 参考:https://pyzh.readthedocs.org/en/latest/Descriptor-HOW-TO-Guide.html


一个对象只要定义了  __get__(self,instance,owner),__set__(self,instance,value),__delete__(self,instance)__其中

的一个或多个,就是一个描述器。


如果一个对象同时定义了 __get__() 和 __set__(),它叫做资料描述器(data descriptor)。仅定义了 __get__() 的描述器叫非资料描述器(特别用于方法,当然其他用途也是可能的)

资料描述器和非资料描述器的区别在于:相对于实例的字典的优先级。如果实例字典中有与描述器同名的属性,如果描述器是资料描述器,优先使用资料描述器,如果是非资料描述器,优先使用字典中的属性。(译者注:这就是为何实例 a 的方法和属性重名时,比如都叫 foo Python会在访问 a.foo 的时候优先访问实例字典中的属性,因为实例函数的实现是个非资料描述器)




其中self 为描述起自身引用,instance是拥有此描述起的实例应用,owner是此描述的拥有者引用(无实例二字)。


class C(object):
    def __init__(self,initval=None,name='Var'):
        self.val=initval
        self.name=name
        
    def __get__(self,obj,objtype):
        print(self,obj,objtype)
        print('Retrieving',self.name)
        return self.val

    def __set__(self,obj,val):
        print('Updating',self.name)
        return self.name

class MyClass(object):
    x=C(10," var 'x'")
    y=5


m=MyClass()

print(m.x)

print(MyClass.x)

无实例时,instance为None

>>> 
<__main__.C object at 0x0000000003262A20> <__main__.MyClass object at 0x000000000330B048> <class '__main__.MyClass'>
Retrieving  var 'x'
10
<__main__.C object at 0x0000000003262A20> None <class '__main__.MyClass'>
Retrieving  var 'x'
10
>>>


Property()  的实现:

class Property(object):
    "Emulate PyProperty_Type() in Objects/descrobject.c"

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError, "unreadable attribute"
        return self.fget(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError, "can't set attribute"
        self.fset(obj, value)

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError, "can't delete attribute"
        self.fdel(obj)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值