python中的描述符
Python描述符(Descriptor)简明笔记
核心概念
描述符是实现了特定协议(__get__、__set__、__delete__)的类,用于精细化控制属性访问。它是@property的底层实现机制。
描述符协议
-
__get__(self, instance, owner)- 访问属性时触发
instance: 调用属性的实例(类访问时为None)owner: 属性所属的类
-
__set__(self, instance, value)- 设置属性时触发
value: 要赋的值
-
__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
关键应用场景
- 类型验证(如示例)
- 延迟计算(首次访问时计算)
- 权限控制(检查访问权限)
- ORM字段映射(如Django模型字段)
- 实现
@property(底层机制)
与普通方法的区别
| 特性 | 描述符 | 普通方法 |
|---|---|---|
| 调用方式 | 自动触发协议方法 | 显式调用 |
| 存储位置 | 类属性 | 实例/类属性 |
| 核心目的 | 控制属性访问 | 执行逻辑 |
注意事项
- 优先使用
@property简化代码(除非需要复用逻辑) - 避免在
__get__中返回描述符自身(需处理instance is None) - 数据描述符会覆盖实例字典的同名属性
描述符是Python元编程的核心工具之一,掌握后可实现高度灵活的属性管理机制。

浙公网安备 33010602011771号