python中@property的使用
在绑定属性时,如果我们将属性直接暴露在外面,就可能导致属性被任意修改,有时候这个是我们不希望看到的
如:设置学生的成绩
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!