python:@property

在绑定参数的时候,如果我们可以绑定任意的值,虽然调用简单,但是不能对参数进行检查:
比如下面的Student类,实例化后可以对年龄随意赋值,显然是不合理的。

'aaa'
>>> class Student(object):
...     pass
...
>>> s = Student()
>>> s.age = 1000
>>> s.age
1000
>>>

当然,我们可以在Studdent内定义get_age()、set_age()方法

>>> class Student(object):
...     def get_age(self):
...             return self.age
...     def set_age(self, age):
...             if not isinstance(age, int):
...                     raise ValueError('age must be an integer!')
...             if age < 0 or age > 100:
...                     raise ValueError('age must between 0 - 100!')
...             self.age = age
...
>>> s = Student()
>>> s.set_age('aa') #传入不是int报错误
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in set_age
ValueError: age must be an integer!
>>> s.set_age(1000) #传入大于100的值报错误
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in set_age
ValueError: age must between 0 - 100!
>>> s.set_age(20)
>>> s.get_age()
20
>>>

有了get、set方法,对任意的Student实例进行操作,就不能随心所欲地设置age了,但是这样比较复杂,调用两个方法去赋值或取值,不如调用一个属性来得方便,有没有既可以检查参数,又能如访问属性一样简单的是访问呢?Decorator修饰器的@property可以。

>>> class Student(object):
...     @property #相当于上面代码的get_age(),把get方法变成属性
...     def age(self):
...             return self._age
...     @age.setter #是@prperty生成的装饰器,把set方法变成属性赋值
...     def age(self, value):
...             if not isinstance(value, int):
...                     raise ValueError('value must be an integer!')
...             if value < 0 or value > 100:
...                     raise ValueError('value must between 0 - 100!')
...             self._age = value
...
>>> s = Student()
>>> s.age = 30 #在范围内的值可以赋值成功
>>> s.age
30
>>> s.age = 'aa' # 不是int报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in age
ValueError: value must be an integer!
>>> s.age = 1000 # 大于范围报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in age
ValueError: value must between 0 - 100!
>>>

也可以只设置getter不设置setter:
下面的name就是只读的而已

class Student(object):
    @property
    def age(self):
        return self._age
    @age.setter
    def age(self, value):
        if not isinstance(value, int):
            raise ValueError('value must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('value must between 0 - 100!')
        self._age = value
    @property
    def name(self):
        return self._age + 20

猜你喜欢

转载自blog.csdn.net/qq_29144091/article/details/81391306