描述符只实用于大型框架
1、描述符是什么?
描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发
描述符代码示例:class Foo: #在python3中Foo是新式类,它实现了三种方法,这个类就被称作一个描述符
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
pass
def __delete__(self, instance):
pass
2、描述符是干什么的?
描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)
2.1 描述符类产生的实例进行属性操作并不会触发三个方法的执行代码实例:class Foo:
def __get__(self, instance, owner):
print('触发get')
def __set__(self, instance, 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, instance, owner):
print('触发get')
def __set__(self, instance, 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>,
del b1.x # 触发delete
3、描述符细分情况:
一 数据描述符:至少实现了__get__()和__set__()class Foo:
def __set__(self, instance, value):
print('set')
def __get__(self, instance, owner):
print('get')
二 非数据描述符:没有实现__set__()class Foo:
def __get__(self, instance, owner):
print('get')
4、描述符注意事项:
一 描述符本身应该定义成新式类,被代理的类也应该是新式类
二 必须把描述符定义成这个类的类属性,不能为定义到构造函数中
三 要严格遵循该优先级,优先级由高到底分别是:
1.类属性
2.数据描述符
3.实例属性
4.非数据描述符
5.找不到的属性触发__getattr__()