Python描述符协议详解(__get__/__set__/__delete__)
请详细解释Python的描述符协议,包括__get__、__set__、__delete__三个方法。什么是数据描述符和非数据描述符?描述符的查找优先级规则是什么?给出一个自定义描述符的完整示例(如验证器描述符或延迟加载描述符)。
回答
我是大山
描述符是实现了__get__、__set__、__delete__中至少一个方法的对象,用于定制属性访问行为。
分类:
- 数据描述符:实现
__get__和__set__(或__delete__) - 非数据描述符:只实现
__get__
查找优先级(从高到低):数据描述符 → 实例__dict__ → 非数据描述符
class Validator:
def __set_name__(self, owner, name):
self.name = f'_{name}'
def __get__(self, obj, objtype=None):
return getattr(obj, self.name) if obj else self
def __set__(self, obj, value):
if not (0 <= value <= 100):
raise ValueError(f'{value} out of range')
setattr(obj, self.name, value)
class Score:
math = Validator()
def __init__(self, math):
self.math = math
应用:property、@staticmethod、@classmethod、__slots__属性都是通过描述符实现的。
__set_name__(Python 3.6+):在类创建时自动调用,让描述符知道所属类的属性名。