• 描述符


    描述符的本质是一个新式类,在这个新式类中,至少实现了__get__()、__set__()、__delete__()中的一个,这也被称为描述符协议

    __get__() :调用一个属性时,触发

    __set__()  :为一个属性赋值时,触发

    __delete__()   :采用del删除属性时,触发

    数据描述符:至少实现了__get__()和__set__()

    非数据描述符:没有实现__set__() 

     1 class Foo:
     2     a = 4
     3 
     4     def __init__(self):
     5         self.name = 'alex'
     6         self.age = 18
     7 
     8     def __get__(self, instance, owner):
     9         print('=====执行get 方法')
    10 
    11     def __delete__(self, instance):
    12         print('调用dele')
    13 
    14     def __set__(self, instance, value):
    15         print('调用set')
    16 
    17 
    18 class New:
    19     x = Foo()
    20 
    21     def __init__(self, n):
    22         self.x = n
    23     # def test(self):
    24     #     print(self.x.a)
    25 
    26 
    27 n1 = New(10)
    28 print(n1.__dict__)
    29 输出:
    30 调用set
    31 {}

    相当于New类中的x属性被Foo() 代理了

    总结:描述符是在一个类中定义,且只能在类属性中定义,不能再类函数中定义,包括__init__函数(初始化函数)。

     1 class Foo:
     2     a = 4
     3 
     4     def __init__(self):
     5         self.name = 'alex'
     6         self.age = 18
     7 
     8     def __get__(self, instance, owner):
     9         print('=====执行get 方法')
    10 
    11     def __delete__(self, instance):
    12         print('调用dele')
    13 
    14     def __set__(self, instance, value):
    15         print('调用set')
    16         instance.__dict__['x'] = value
    17 
    18 
    19 class New:
    20     x = Foo()
    21 
    22     def __init__(self, n):
    23         self.x = n
    24     # def test(self):
    25     #     print(self.x.a)
    26 
    27 
    28 n1 = New(10)
    29 # n1.y = 545
    30 print(n1.__dict__)
    31 输出:
    32 调用set
    33 {'x': 10}

    调用优先级:

    1.类属性     2.数据描述符    3.实例属性    4.非数据描述符     5.找不到的属性触发__getatr__()

     1 class Foo:
     2     a = 4
     3 
     4     def __init__(self):
     5         self.name = 'alex'
     6         self.age = 18
     7 
     8     def __get__(self, instance, owner):
     9         print('=====执行get 方法')
    10 
    11     def __delete__(self, instance):
    12         print('调用dele')
    13 
    14     def __set__(self, instance, value):
    15         print('调用set')
    16         instance.__dict__['x'] = value
    17 
    18 
    19 class New:
    20     x = Foo()
    21 
    22     # def __init__(self, n):
    23     #     self.x = n
    24     # def test(self):
    25     #     print(self.x.a)
    26 
    27 
    28 print(New.x)   #  从类属性中找,直接触发描述符
    29 # New.x = 2   # 按照优先级,先访问类属性,类属性没有,直接创建,不会访问描述符
    30 # # print(New.__dict__)
    31 # # n1 = New()
    32 n1 = New()
    33 n1.x = 3   # 描述符大于实例属性
    34 n1.x
    35 输出:
    36 =====执行get 方法
    37 None
    38 调用set
    39 =====执行get 方法
  • 相关阅读:
    C++ 使用老牌库xzip & unzip对文件进行压缩解压
    第一次玩蛇,有点紧张。
    fiddler 抓取手机http/https包
    disk或者Partition镜像的制作
    VS2013+phread.h环境配置
    C++ 浅谈 strlen 与 sizeof的区别
    Qt 显示网页的控件
    Qt error: C2236: 意外的标记“class”。是否忘记了“;”?
    初识MySQL——人生若如初相逢
    【学习笔记】HTML基础:列表、表格与媒体元素
  • 原文地址:https://www.cnblogs.com/ch2020/p/12452579.html
Copyright © 2020-2023  润新知