在绑定属性时,如果我们将属性直接暴露在外面,就可能导致属性被任意修改,有时候这个是我们不希望看到的
如:设置学生的成绩
class Student(object):
def __init__(self):
self.score = 0
#这个显然不符合属性的规范
#std = Student()
#std.score = 99999
#print std.score
#于是我们采用内部限制的方法来设定
1 class Student2(object):
2 def __init__(self):
3 pass
4
5 def get_score(self):
6 return self._score
7
8 def set_score(self, value):
9 if not isinstance(value, int):
10 raise ValueError('score must be an integer!')
11 if value < 0 or value > 100:
12 raise ValueError('score must between 0 ~ 100!')
13 self._score = value
14
15
16 std2 = Student2()
17 std2.set_score(60)
18 print std2.get_score() #60
19
20 std2.set_score(99999)
21 print std2.get_score()
22
23 Traceback (most recent call last):
24 File "/home/mywork/oldboy/practice/property.py", line 44, in <module>
25 std2.set_score(99999)
26 File "/home/mywork/oldboy/practice/property.py", line 35, in set_score
27 raise ValueError('score must between 0 ~ 100!')
28 ValueError: score must between 0 ~ 100!
#但是,上面的调用方法又略显复杂,这就是需要应用@property
#他的本质就是把一个getter方法变成属性
#此时,@property本身又创建了另一个装饰器@score.setter,
#负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:
看代码:
1 class Student3(object):
2
3 @property
4 def score(self):
5 return self._score
6
7 @score.setter
8 def score(self, value):
9 if not isinstance(value, int):
10 raise ValueError('score must be an integer!')
11 if value < 0 or value > 100:
12 raise ValueError('score must between 0 ~ 100!')
13 self._score = value
14
15 std3 = Student3()
16 std3.score = 90
17 print std3.score #90
18 std3.score = 9000 #直接设置时就报错
19
20 Traceback (most recent call last):
21 File "/home/mywork/oldboy/practice/property.py", line 69, in <module>
22 std3.score = 9000
23 File "/home/mywork/oldboy/practice/property.py", line 63, in score
24 raise ValueError('score must between 0 ~ 100!')
25 ValueError: score must between 0 ~ 100!