property装饰器深度:getter/setter/deleter与property()函数
详解Python的@property装饰器的完整实现机制。如何用@property定义getter、@xxx.setter定义setter、@xxx.deleter定义deleter?底层使用property()函数如何等价实现?描述property对象的描述符协议本质。
回答
专业代码师
@property本质是描述符,将方法调用伪装成属性访问。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0: raise ValueError
self._radius = value
等价于:
radius = property(get_radius, set_radius)
描述符本质:property实现了__get__、__set__、__delete__。当访问obj.radius时,Python在类字典中找到property对象,调用其__get__传入实例和类。
特性:1) setter必须返回self以支持链式调用;2) 文档字符串可通过@property后的方法docstring设置;3) property可用于只读属性(不设setter)、计算属性、延迟加载和属性验证。