加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python3面对像进阶--描述符(__get__,__set__,__delete__)

发布时间:2020-12-17 17:02:07 所属栏目:Python 来源:网络整理
导读:描述符只实用于大型框架 1、描述符是什么? ????描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议 ????__get__():调用一个属性时,触发 ????__set__():为一个属性赋值时,触发 ????__delete_

描述符只实用于大型框架


1、描述符是什么?

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

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

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

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

描述符代码示例:

class?Foo:?#在python3中Foo是新式类,它实现了三种方法,这个类就被称作一个描述符
????def?__get__(self,?instance,?owner):
????????pass
????def?__set__(self,?value):
????????pass
????def?__delete__(self,?instance):
????????pass


2、描述符是干什么的?

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

2.1 描述符类产生的实例进行属性操作并不会触发三个方法的执行代码实例:

class?Foo:
????def?__get__(self,?owner):
????????print('触发get')
????def?__set__(self,?value):
????????print('触发set')
????def?__delete__(self,?instance):
????????print('触发delete')
#包含这三个方法的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法
f1=Foo()
f1.name='egon'
f1.name
del?f1.name

2.2 描述符被使用代码实例:

class?Foo:
??def?__get__(self,?owner):
?????print('触发get')
??def?__set__(self,?value):
?????print('触发set')
?????#?instance.__dict__['x']?=?value????#?传入值
??def?__delete__(self,?instance):
?????print('触发delete')
class?Bar:
??x?=?Foo()
????def?__init__(self,?n):
????????self.x?=?n
????
b1?=?Bar(10)????????????#?触发set
b1.x????????????????????#?触发get
print(b1.__dict__)??????#?空值
print(Bar.__dict__)?????#?'x':?<__main__.Foo?object?at?0x00000238F0B6D940>,del?b1.x????????????????#?触发delete

3、描述符细分情况:

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

class?Foo:
????def?__set__(self,?value):
print('set')
????def?__get__(self,?owner):
print('get')

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

class?Foo:
????def?__get__(self,?owner):
print('get')

4、描述符注意事项:

一 描述符本身应该定义成新式类,被代理的类也应该是新式类

二 必须把描述符定义成这个类的类属性,不能为定义到构造函数中

三 要严格遵循该优先级,优先级由高到底分别是:

????1.类属性

????2.数据描述符

????3.实例属性

????4.非数据描述符

????5.找不到的属性触发__getattr__()


(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读