在 Python 中,装饰器 @property 允许创建 "虚拟" 属性 — 看起来和使用起来像普通字段的方法,但执行 getter、setter 或 deleter 的逻辑。这对于创建计算属性或控制数据访问非常方便。
示例:
class Rectangle: def __init__(self, width, height): self._width = width self._height = height @property def area(self): return self._width * self._height @property def width(self): return self._width @width.setter def width(self, value): if value <= 0: raise ValueError('Width must be positive') self._width = value r = Rectangle(3, 4) print(r.area) # 12 (作为属性调用,而不是函数) r.width = 10 # setter 自动调用
可以只使用一个 @property(get 方法),而不定义 setter 吗?如果试图修改这样的属性会发生什么?
答案: 可以只定义 getter @property 而不定义 setter(和 deleter)。这样的属性将是只读的,赋值尝试将引发 AttributeError。
class C: @property def x(self): return 42 c = C() c.x = 99 # AttributeError: can't set attribute
故事
试图使用标准库序列化对象,通过使用 vars(obj) 获取属性字典。结果发现 property 方法不包括在 __dict__ 的输出中,它们的值未被序列化,导致数据泄露。
故事
项目中忘记为 property 添加 setter,最终尝试更改计算字段的值导致运行时错误,尽管在架构逻辑中这是可以预期的。
故事
在工作代码中,计算 property 值时允许进行繁重或不安全的操作,这在每次访问属性时都会意外触发。这降低了性能,并导致多线程代码中的阻塞调用。