python中,我们可以直接添加和修改属性的值:
>>> class Student(object): ... pass ... >>> s = Student() >>> s.score = 101
但是,101明显超过了满分100分,不合理。可以通过创建setScore()方法,进行参数检查:
>>> class Student(object): ... def setScore(self,score): ... if not isinstance(score,int): ... raise ValueError('分数必须是一个整数') ... if score < 0 or score > 100: ... raise ValueError('分数值必须在0到100之间') ... self.score = score ... def getScore(self): ... return self.score ... >>> s = Student() >>> s.setScore(200) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in setScore ValueError: 分数值必须在0到100之间 >>> s.setScore(99) >>> s.getScore() 99
但是上面的过程略显复杂。
这时,可以使用@property,既可以用类似属性的方法访问类的变量,又可以检查参数,@property实现起来稍微有点复杂:
>>> class Student(object): ... @property ... def score(self): ... return self._score ... @score.setter ... def score(self,score): ... if not isinstance(score,int): ... raise ValueError('必须是整数') ... if score < 0 or score > 100: ... raise ValueError('必须在0到100之间') ... self._score = score ... >>> s = Student() >>> s.score = 88 >>> s.score = 55 >>> s.score = 101 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 10, in score ValueError: 必须在0到100之间
把一个getter方法变成属性,只需要加上@property即可,同时,@property本身又创建了另外一个装饰器@score.setter,该装饰器负责把一个setter方法变成属性赋值。
另外,只定义getter方法,不定义setter方法就是在定义一个只读属性:
>>> class Student(object): ... @property ... def birth(self): ... return self._birth ... @birth.setter ... def birth(self,birth): ... self._birth = birth ... @property ... def age(self): ... return 2018 - self._birth ... >>> s =Student() >>> s.birth = 1991 >>> s.birth 1991 >>> s.age 27 >>> s.age = 20 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can't set attribute
最后一步,证明了age只是一个只读属性!
笑声激发自强,发愤、图强、飞身向上