参考资料:廖雪峰的Python教程、python中 @property
具体代码如下:
# 采用以下装饰器方式 只是为了在检查输入属性的值外,还能保持原有的属性访问方式 class Student(object): def __init__(self, name, score): self.name = name self.__score = score @property # get方法 将属性score作为一个方法 def score(self): return self.__score @score.setter # set方法 由于score是一个私有属性 所有要有专门的set方法 这里将score属性作为一个方法 def score(self, score): if score < 0 or score > 100: raise ValueError('invalid score') self.__score = score obj = Student('Daniel', 99) print(obj.score) obj.score = -2 # 不符合 将会报错 print(obj.score)
然后输出的结果为:
D:\Python\venv\Scripts\python.exe D:/Python/PythonLearning/test/to_property.py Traceback (most recent call last): File "D:/Python/PythonLearning/test/to_property.py", line 22, in <module> obj.score = -2 # 不符合 将会报错 File "D:/Python/PythonLearning/test/to_property.py", line 14, in score raise ValueError('invalid score') ValueError: invalid score 99 Process finished with exit code 1
总结:刚开始看到这节内容时,没看明白~然后搜了一些资料后,仔细琢磨了一下,大概懂了。
由于某些属性对输入的值有要求,比如学生成绩,如果是满分100分制的,那么成绩的合理取值范围为0~100,因此必须对输入的score进行检查。于是想到可以使score成为Student对象的私有属性,再添加对应的set_score(),get_score()方法来设置和获取score(因为私有属性不能直接添加或者获取)。
但是,这样做就使得每次设置或获取score的代码必须写成(假设对象实例为a)a.set_score()和a.get_score()(这里只是说将score变成私有属性后,必须要有设置和获取score的两个方法,并且这两个方法一定与score不重名!否则就有歧义了)。
这种形式很“繁琐”,又想到了Python中可以将方法名赋值给一个变量,于是就有了以上形式的装饰器方法。这使得能够满足检查属性值的同时,还能保证原先的方便访问形式!
然而,最后想吐嘲一下,其实我觉得采用a.set_score()和a.get_score()这种形式访问score,也没这么“繁琐”吧???弄个装饰器的方法,真地容易让人属性和方法傻傻分不清~~~