在创建实例属性时,如果直接把实例属性暴露出去,虽然写起来简单,但是存在一些风险,比如实例属性可以在外部被修改。

为了限制外部操作,可以通过一个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()的第三个方法。注意:实际项目中很少用该方法。

上面两种方法最终实现的效果是一样的,也没有使用限制,喜欢用哪种就用哪种!

最新文章

  1. ASP.NET MVC Web API 学习笔记---第一个Web API程序
  2. TFS 2013&rdquo;无法移除仍为团队管理员身份的标识&rdquo;
  3. 2012杀毒软件排行榜TOP10强
  4. Private strand flush not complete
  5. Solr4.8.0源码分析(11)之Lucene的索引文件(4)
  6. Sublime text 3 格式化HTML/css/js/json代码 插件
  7. codeforces 166C Median - from lanshui_Yang
  8. [CF486D]有效集合-树形dp
  9. Linux系统中cgroup功能介绍
  10. LeetCode 73. Set Matrix Zeros(矩阵赋零)
  11. 我也来写spring
  12. 使用Java 线程池的利弊及JDK自带六种创建线程池的方法
  13. JS对象、构造器函数和原型对象之间的关系
  14. Java学习笔记之——Manth类和String类
  15. Ajax的beforeSend
  16. stm32 修改工作频率
  17. sencha touch list(列表) item(单行)单击事件触发顺序
  18. 使用 ahk 让普通键盘变为Dvorak键盘
  19. C++:fread、fwrite函数用法
  20. MongoDB实战开发

热门文章

  1. 什么是maven(二)
  2. Git初始化及仓库创建和操作
  3. 学习笔记--html篇(2)
  4. IOS 委托代理(delegate)实现页面传值
  5. [BUUCTF]PWN——wustctf2020_closed
  6. SWPUCTF 2019 pwn writeup
  7. LuoguP1723 高手过愚人节 题解
  8. CF1437A Marketing Scheme 题解
  9. 55 道MySQL基础题
  10. java 编程基础 Class对象 反射 :参数反射