python面向对象高级编程:使用@property

在Python的面向对象编程中,@property 是一个内置的装饰器,它允许将类的方法当作属性来访问。这种机制使得可以对属性的获取(getter)和设置(setter)进行细粒度的控制,同时保持属性访问的简洁性。

基本用法

@property 装饰器通常用于将一个方法转换为只读属性。如果还需要控制属性的设置,可以使用 @<属性名>.setter 装饰器。

示例:只读属性
复制代码

python复制代码

|---|---------------------------------------------------------|
| | class Circle: |
| | def __init__(self, radius): |
| | self._radius = radius # 私有属性,通常使用单下划线或双下划线前缀来表示 |
| | |
| | @property |
| | def radius(self): |
| | """获取圆的半径""" |
| | return self._radius |
| | |
| | @property |
| | def diameter(self): |
| | """获取圆的直径,只读""" |
| | return self._radius * 2 |
| | |
| | @property |
| | def area(self): |
| | """获取圆的面积,只读""" |
| | return 3.14159 * self._radius ** 2 |
| | |
| | # 创建一个 Circle 实例 |
| | c = Circle(5) |
| | |
| | # 访问只读属性 |
| | print(c.radius) # 输出: 5 |
| | print(c.diameter) # 输出: 10.0 |
| | print(c.area) # 输出: 78.53975 |
| | |
| | # 尝试设置只读属性(会报错) |
| | # c.radius = 10 # AttributeError: can't set attribute |

示例:带有setter的属性
复制代码

python复制代码

|---|-----------------------------------------------------------|
| | class CircleWithSetter: |
| | 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("Radius cannot be negative") |
| | self._radius = value |
| | |
| | # 创建一个 CircleWithSetter 实例 |
| | c = CircleWithSetter(5) |
| | |
| | # 访问和设置属性 |
| | print(c.radius) # 输出: 5 |
| | c.radius = 10 # 设置新的半径 |
| | print(c.radius) # 输出: 10 |
| | |
| | # 尝试设置非法的半径值(会报错) |
| | # c.radius = -1 # ValueError: Radius cannot be negative |

使用场景

  • 封装:隐藏对象的内部实现细节,只暴露必要的接口时。
  • 验证:需要在设置属性值时执行验证逻辑时。
  • 只读属性:某些属性只能被读取而不能被修改时。
  • 懒加载:第一次访问属性时才计算其值时。

注意

  • 使用 @property 可以使代码更加清晰和易于理解。
  • 不要滥用 @property,用于逻辑上应该是属性的东西,而不是用于所有方法。
  • 如果在类中使用了 @property,并且还需要一个对应的setter方法,请确保同时提供 @<属性名>.setter
  • 虽然 @property 提供了对属性访问的细粒度控制,但它也增加了代码的复杂性。在简单的情况下,直接使用普通的属性可能更为合适。
相关推荐
X56612 小时前
如何在 Laravel 中正确保存嵌套动态表单数据(主服务与子服务)
jvm·数据库·python
FQNmxDG4S2 小时前
Java多线程编程:Thread与Runnable的并发控制
java·开发语言
ZhengEnCi2 小时前
03ab-PyTorch安装教程 📚
python
前端老石人3 小时前
HTML 字符引用完全指南
开发语言·前端·html
matlab_xiaowang3 小时前
Redux 入门:JavaScript 可预测状态管理库
开发语言·javascript·其他·ecmascript
狐狐生风3 小时前
LangChain 向量存储:Chroma、FAISS
人工智能·python·学习·langchain·faiss·agentai
虹科网络安全3 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
狐狐生风3 小时前
LangChain RAG 基础
人工智能·python·学习·langchain·rag·agentai
axng pmje4 小时前
Java语法进阶
java·开发语言·jvm
老前端的功夫4 小时前
【Java从入门到入土】28:Stream API:告别for循环的新时代
java·开发语言·python