描述符
目录
1 定义 .
2 为什么要用描述符.
3 描述符的调用机制 .
4 描述符的种类.
5 描述符的参数.
一 定义 :
首先要有一个实现了__get__()、set()和__delete__()中的其中任意一种方法的新式类,
如果一个类有个属性是上述的类的实例化对象,那么这个属性(也就是那个实例化对象),就是一个描述符。
下面代码的m,就是M类的实例对象,而M有那三种方法(get,set,deelte), 所有称m就是描述符
class M:
def __init__(self, x=1):
print("经过初始化")
self.x = x
def __get__(self, instance, owner):
print("经过get")
return self.x
def __set__(self, instance, value):
print("经过set")
self.x = value
def __delete__(self, instance):
print("经过delete")
# 调用描述符的类
class AA:
m = M() # m就是一个描述符
aa = AA()
aa.m
aa.m = 777
del aa.m
注意m必须用类属性形式写。
- 实例化aa的时候,会先走M的初始化,因为定义类AA的时候,就已经实例化m了
- 调用aa.m的时候,会走描述符m的get方法
- 给m赋值的时候,会走描述符m的set方法
- 删除aa.m 的时候会走delete方法
描述符是加强版的property访问属性其实走的是方法
二 为什么要用描述符 ?
因为可以做类型检查
Python是一个动态类型解释性语言,不像C/C++等静态编译型语言,数据类型在编译时便可以进行验证,而Python中必须添加额外的类型检查逻辑代码才能做到这一点,这就是描述符的初衷.\
三 描述符的调用机制
使用__dict__查看,下面简单说调用aa.m时候的访问顺序
简单说就是先找对象a的dict,没有再去找对象所在的类的dict,还没有再找a的类的父类的dict
期间: 期间找到的是普通值就输出,如果找到的是一个描述符,则调用__get__方法
四 描述符的种类
- 同时定义了__get__和__set__方法的描述符称为数据描述符
- 只定义了__get__的描述符称为非数据描述符
- 二者的区别是:当属性名和描述符名相同时,在访问这个同名属性时,如果是数据描述符就会先访问描述符,如果是非数据描述符就会先访问属性
五 描述符的参数
-
__get__方法里的instance, owner参数是什么?
-
__set__里的instance, value是什么?__delete__方法里的instance是什么?
instance是AA的实例化对象aa,owner就是AA这个类对象,value就是设置属性时候传入的值