python中的描述符

Python描述符(Descriptor)简明笔记

核心概念

描述符是实现了特定协议(__get____set____delete__)的类,用于精细化控制属性访问。它是@property的底层实现机制。


描述符协议

  1. __get__(self, instance, owner)

    • 访问属性时触发
    • instance: 调用属性的实例(类访问时为None
    • owner: 属性所属的类
  2. __set__(self, instance, value)

    • 设置属性时触发
    • value: 要赋的值
  3. __delete__(self, instance)

    • 删除属性时触发

注:实现任意一个方法即成为描述符


两种类型

类型 定义 优先级
数据描述符 实现__set____delete__ 高于实例字典
非数据描述符 仅实现__get__ 低于实例字典

经典示例

class PositiveNumber:
    """数据描述符:强制数值为正数"""
    def __init__(self, name):
        self.name = name  # 属性名称

    def __get__(self, instance, owner):
        return instance.__dict__[self.name]

    def __set__(self, instance, value):
        if value <= 0:
            raise ValueError("必须为正数")
        instance.__dict__[self.name] = value

class Order:
    quantity = PositiveNumber('quantity')  # 描述符绑定到属性

    def __init__(self, qty):
        self.quantity = qty  # 触发__set__

# 测试
order = Order(10)
print(order.quantity)  # 10
order.quantity = -5    # 触发 ValueError

关键应用场景

  1. 类型验证(如示例)
  2. 延迟计算(首次访问时计算)
  3. 权限控制(检查访问权限)
  4. ORM字段映射(如Django模型字段)
  5. 实现@property(底层机制)

与普通方法的区别

特性 描述符 普通方法
调用方式 自动触发协议方法 显式调用
存储位置 类属性 实例/类属性
核心目的 控制属性访问 执行逻辑

注意事项

  1. 优先使用@property简化代码(除非需要复用逻辑)
  2. 避免在__get__中返回描述符自身(需处理instance is None
  3. 数据描述符会覆盖实例字典的同名属性

描述符是Python元编程的核心工具之一,掌握后可实现高度灵活的属性管理机制。

posted @ 2025-08-29 12:02  清澈的澈  阅读(8)  评论(0)    收藏  举报