美文网首页
32.3-描述器Descriptors概念

32.3-描述器Descriptors概念

作者: BeautifulSoulpy | 来源:发表于2020-01-01 08:18 被阅读0次

    人生苦短,所以每天不要带着遗憾醒来!

    总结:

    1. 数据描述器比我们实例字典优先;
    2. 知道不同条件下谁优先的就行;与反射的方法不可混用;

    描述器

    Python中,一个类实现了 _get_ 、 _set_ 、 _delete_ 三个方法中的任何一个方法,就是描述器。
    如果仅实现了 _get_ ,就是非数据描述符 non-data descriptor
    同时实现了 _get_ 、 _set_ 就是数据描述符 data descriptor
    如果一个类的类属性设置为描述器实例,那么它被称为owner属主。

    用到3个魔术方法: _get_() 、 _set_() 、 _delete_()
    方法签名如下
    object._get(self, instance, owner)
    object._set
    (self, instance, value)
    object._delete_(self, instance)
    self指代当前实例,调用者
    instance 是owner的实例
    owner 是属性的所属的类

    class A:
        def __init__(self):
            print('A().init~~~~~~~~~~')
            self.a1 = 100
        
        def __get__(self,instance,owner):
            print(self)   #A实例本身
            print(instance)  # None,如果使用B的实例来访问,B的实例;
            print(owner)  #B
            print("~~~~~~~~~~~~~~~~~~~")
            return self
            
        def __set__(self,instance,value):
            print(self)
            print(instance)
            print(value)
            print('--------------------')
            
        def __delete__(self,instance):
            print(instance)
            
    class B:
        x = A()
        def __init__(self):
            print('B().init~~~~~~~~~~~~~')
    print(B.x)
    #----------------------------------------------------
    A().init~~~~~~~~~~
    <__main__.A object at 0x000002089F30DCC0>
    None
    <class '__main__.B'>
    ~~~~~~~~~~~~~~~~~~~
    None
    
    

    描述器由两个类构成:而类B的x属性是类A的实例,所以类A先初始化,所以打印A.init。
    然后执行到打印B.x.a1。

    因为定义了 _get_ 方法,类A就是一个描述器,对类B或者类B的实例的x属性读取,成为对类A的实例的访问,就会调用 _get_ 方法

    访问: _get(self, instance, cls) # instance 代表实例本身,cls 表示类本身,使用类直接访问时,instance 为 None
    赋值: _set
    (self, instance, value) # instance 为实例,value 为值
    删除: _delete_(self, instance) # instance 为实例

    相关文章

      网友评论

          本文标题:32.3-描述器Descriptors概念

          本文链接:https://www.haomeiwen.com/subject/yyamoctx.html