Python python 的类的特性:描述符

醋精测试媛 · 2021年03月31日 · 最后由 醋精测试媛 回复于 2021年04月13日 · 2543 次阅读

之前初步学了一下 python,然后就开始写自动化了,感觉确实 python 很多时候很方便,但是一直觉得 python 好像不太 “重视” 类和对象的样子,后来才发现其实是自己的懒惰心理,觉得__iter__什么的好像不太用得上,所以就忽视了这些。
上次提了一个小问题【 https://testerhome.com/topics/29215 】,刚开始自己写怎么也写不出来,发现还是要啃 python 的内部函数这块硬骨头,发现自己走了第一步之后就能下定决心去看别的内容啦。
只是在这里记一下笔记,不作别的用途。

class Example:
    def __get__(self, instance, owner):
        print('触发get')

    def __set__(self, instance, value):
        print('触发set')

    def __delete__(self, instance):
        print('触发delete')
# 包含这三个方法(__get__(),__set__(),__delete__())的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法
e1 = Example()
e1.name = 'name'
print(e1.name) # 这里会输出
del e1.name
print(e1.name)

输出了一下,只有一个'name', 即 print 里面的东西不会有输出。
另外,print(e1.name)第二次输出时,会报错,Example object has no attribute 'name'

描述符的作用是用来代理另外一个类的属性的 (必须把描述符定义成这个类的类属性,不能定义到构造函数中)

# 描述符People
# 该描述符的作用是为另外一个类的类属性进行服务,另外一个类就是描述符的对象
class People:
    def __get__(self, instance, owner):
        print('People调用')
        print(instance, owner)

    def __set__(self, instance, value):
        # 实现__set__()即数据描述符,没有实现__set__()即非数据描述符
        print('People设置...')
        print(instance, value)

    def __delete__(self, instance):
        print('People删除...')
        print(instance)


class Student:
    name = People()  # name 属性被代理,将这个类作用于另外一个类的属性来使用  **必须把描述符定义成这个类的类属性,不能为定义到构造函数中**

    def __init__(self, name):  # name被People类代理
        self.name = name  


s1 = Student('long')

# 描述符People的使用
print(s1.name)
s1.name = 'sss'
del s1.name

print(s1.__dict__)
print(Student.__dict__) # 列出属性

输出结果:

共收到 2 条回复 时间 点赞

关于描述符的最详细介绍还是推荐看 python3.9 的官方文档中关于描述符的 how to 部分,从实现到使用都有很详细的介绍。另外,你之前帖子中那个问题,有一个 sortedcontainer 库可以直接使用,那个库实现了很多排序容器,而且效率很高

Neo Chen 回复

谢谢~学到了!

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册