Python @property高级应用技巧
一、数据校验与约束
这是@property最常见的用途。当你需要确保某个属性的值符合特定规则时(例如,年龄不能为负数),可以使用它:
- 传统方式:需要显式调用
set_age()方法 - 使用@property:可以像给普通属性赋值一样
obj.age = 25,但赋值操作会触发你预设的校验逻辑
1 | class Person: |
二、创建计算属性(只读属性)
有些值并非直接存储,而是由其他属性动态计算得出,比如圆的面积、矩形的周长。使用@property可以将这些计算方法变成只读属性:
- 传统方式:需要调用
get_area()方法 - 使用@property:可以直接访问
obj.area,语义更清晰,调用方也无需关心这个值是存储的还是计算的
1 | class Circle: |
三、保持向后兼容性
这是@property的一个高级但极其重要的用途。假设你最初将一个属性设计为公开属性,后来发现需要增加校验逻辑:
- 不使用@property:你需要将所有
obj.attr的调用改为obj.set_attr(),这会破坏已有的代码 - 使用@property:你可以将公开属性重构为@property,而所有调用方代码
obj.attr无需任何改动,实现了无缝升级
四、完整语法:Getter, Setter, Deleter
@property体系包含三个装饰器,让你可以完全控制属性的访问、修改和删除行为:
| 装饰器 | 作用 | 触发时机 |
|---|---|---|
| @property | 定义getter方法 | 当读取属性时,如obj.attr |
| @attr.setter | 定义setter方法 | 当设置属性时,如obj.attr = value |
| @attr.deleter | 定义deleter方法 | 当删除属性时,如del obj.attr |
1 | class Example: |
五、注意事项
- 避免耗时操作:@property方法在执行时看起来就像访问一个普通属性,因此不应在其中执行耗时操作(如网络请求、复杂计算),否则会让调用方在不经意间感到程序卡顿
- 不要过度使用:对于简单的、无需任何逻辑的数据存储,直接使用公开属性是更简单、更高效的选择。@property应该用在"需要逻辑控制"的场景
- 避免循环引用:在getter或setter方法内部,务必访问带下划线的内部属性(如
_value),而不是属性本身(如self.value),否则会引发无限递归
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.

