Python描述符是一种“绑定行为”的对象属性。在描述符协议中,它可以通过方法重写属性访问。本质上,描述符是一个类,但它定义了另一个类中属性的访问方式;换句话说,一个类可以将属性管理委托给描述符。
在Python中,通过使用描述符,程序员可以在引用对象属性时定制要完成的工作。本质上,描述符是一个类,但它定义了另一个类中属性的访问方式。换句话说,一个类可以将属性管理委托给描述符类。
描述符是 Python 在内部实现中复杂属性访问的基础 property、方法、类法、静态方法和 super 类型。
以下是基于描述符类的 3 换句话说,这是一种特殊的方法 3 描述符协议由一种方法组成:
__set__(self, obj, type=None):此方法将在设置属性时调用(本节后续使用) setter 表示);
__get__(self, obj, value):此方法将在读取属性时调用(本节后续使用) getter 表示);
__delete__(self, obj):对属性调用 del 这种方法将被调用。
其中,实现了 setter 和 getter 该方法的描述符类称为数据描述符;相反,如果只实现 getter 该方法称为非数据描述符。事实上,在每次搜索属性时,描述符协议中的方法都是由类对象的特殊方法组成的 __getattribute__() 调用(注意不要和 __getattr__() 混淆)。也就是说,每次使用类对象。属性(或 getattr(类对象,属性值))在调用方式时,会隐式调用 __getattribute__(),它将按以下顺序找到该属性:
验证该属性是否是类实例对象的数据描述符;
如果没有,检查该属性是否可以作为类实例对象 __dict__ 中找到;
最后,检查该属性是否是类实例对象的非数据描述符。
为了表达清楚,这里举个例子:#描述符类
classrevealAccess: def__init__(self,initval=None,name='var'): self.val=initval self.name=name def__get__(self,obj,objtype): print("Retrieving",self.name) returnself.val def__set__(self,obj,val): print("updating",self.name) self.val=val classmyClass: x=revealAccess(10,'var"x"') y=5 m=myClass() print(m.x) m.x=20 print(m.x) print(m.y)
运行结果如下:
Retrievingvar"x" 10 updatingvar"x" Retrievingvar"x" 20 5
从这个例子中可以看出,如果一个类的某个属性有数据描述符,那么每次搜索这个属性时,都会调用描述符 __get__() 方法,并返回其值;同样,每次赋值属性时,也会调用 __set__() 方法。
请注意,尽管上述例子没有使用 __del__() 方法,但也很容易理解,当每次使用时 del 类对象.属性(或) delattr(类对象,属性))这种方法在句子中被调用。
推荐课程:Python 基本入门教程