Python 利用@property装饰器和property()方法将一个方法变成属性调用
2024-09-02 02:44:04
在创建实例属性时,如果直接把实例属性暴露出去,虽然写起来简单,但是存在一些风险,比如实例属性可以在外部被修改。
为了限制外部操作,可以通过一个set_score()
方法来设置成绩,再通过一个get_score()
来获取成绩,在这些方法中还可以增加一些检查操作,比如在get_score中增加获取权限操作,在set_score中增加输入检查操作。
class Student(object): def __init__(self):
self._score = 60 def get_score(self):
print(self._score)
return self._score def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value if __name__ == "__main__":
s = Student()
s.get_score()
s.set_score("aaa") # 语法报错
现在,对任意的Student实例进行操作,就不能随心所欲地设置score了。但是,上面的调用方法又略显复杂,没有直接调用属性这么直接简单。
有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?对于追求完美的Python程序员来说,这是必须要做到的!
方法一:使用@property装饰器
@property装饰器可以把一个类方法以获取属性的方式进行调用。@property装饰器只能获取值,如果要进行赋值或删除操作,就要使用到伴生装饰器@XXX.setter和@XXX.deleter(XXX为@property装饰的方法名称)
被@XXX.setter装饰的方法在赋值时被调用
被@XXX.deleter装饰的方法在对象被删除时被调用
class Student(object): def __init__(self):
self._score = 60 @property # 取值操作
def score(self):
print("@property被调用")
return self._score @score.setter # 赋值操作
def score(self, value): # 赋予的值传给value
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
print("@score.setter被调用") @score.deleter # 删除操作
def score(self):
self._score = 0
print("@score.deleter被调用") if __name__ == "__main__":
s = Student()
s.score # 当获取属性值时执行@property
s.score = 99 # 当赋值属性值时执行 @**.setter
del s.score # 当删除属性值时执行 @**.deleter
执行结果为:
方法二:使用property()创建类属性
第二种方式看起来与使用@property装饰器之前的方式相差不大,唯一不同的是使用了property()方法创建了一个类属性
class Student(object): def __init__(self):
self._score = 60 def get_score(self):
print(self._score)
return self._score def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
print(f"修改score为{self._score}") def del_score(self):
self._score = 0
print("删除score") score = property(get_score, set_score, del_score) if __name__ == "__main__":
s = Student()
s.score # 当获取属性值时,执行property()的第一个方法
s.score = 99 # 当赋值属性值时,执行property()的第二个方法
del s.score # 当删除属性值时执行,执行property()的第三个方法。注意:实际项目中很少用该方法。
上面两种方法最终实现的效果是一样的,也没有使用限制,喜欢用哪种就用哪种!
最新文章
- ASP.NET MVC Web API 学习笔记---第一个Web API程序
- TFS 2013&rdquo;无法移除仍为团队管理员身份的标识&rdquo;
- 2012杀毒软件排行榜TOP10强
- Private strand flush not complete
- Solr4.8.0源码分析(11)之Lucene的索引文件(4)
- Sublime text 3 格式化HTML/css/js/json代码 插件
- codeforces 166C Median - from lanshui_Yang
- [CF486D]有效集合-树形dp
- Linux系统中cgroup功能介绍
- LeetCode 73. Set Matrix Zeros(矩阵赋零)
- 我也来写spring
- 使用Java 线程池的利弊及JDK自带六种创建线程池的方法
- JS对象、构造器函数和原型对象之间的关系
- Java学习笔记之——Manth类和String类
- Ajax的beforeSend
- stm32 修改工作频率
- sencha touch list(列表) item(单行)单击事件触发顺序
- 使用 ahk 让普通键盘变为Dvorak键盘
- C++:fread、fwrite函数用法
- MongoDB实战开发