Python Property Decorator [Python的Property装饰器]
Published: Jan. 21, 2022
本文介绍一个python常用的装饰器Property,其主要作用就是解决python class的属性的setter和getter,和类属性保护的问题。
首先枷梢我们有一个Student
类,其中有一个name
的属性。
s = Student()
s.name = 'xuesheng'
但是,因为Python并没有属性保护机制,所以可以通过类实例直接访问name
属性[直接把name
暴露出去]。同时,我们也没有办法进行属性检测,比如对name
我们可能有一些格式要求,在赋值之前需要先检测格式。这显然不合逻辑。所以,我们可以通过一个set_name()
方法来设置名字,再通过一个get_name()
来获取名字,这样,在set_name()
方法里,就可以检查名字。
class Student(object):
def get_name(self):
return self._name
def set_name(self, value):
if not isinstance(value, str):
raise ValueError('name must be a string!')
self._name = value
但是,上面的方法又略显复杂,通过@property
方式就可以兼顾。Python内置的@property
装饰器就是负责把一个方法变成属性调用的。
class Student(object):
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not isinstance(value, str):
raise ValueError('name must be a string!')
self._name = value
把一个getter方法变成属性,只需要加上@property
就可以了,此时,@property
本身又创建了另一个装饰器@name.setter
,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:
s = Student()
s.name = 'xuesheng' #实际就是`set_name('xuesheng')`
s.name #实际调用的是`get_name()`
需要注意的是,即便使用@property
也不能防止通过类实例来访问属性,比如上面例子中,s._name
依然是合法的。
@property
广泛应用在类的定义中,可以让开发者写出简短的代码,同时保证对参数进行基本的保护和必要的检查,这样,程序运行时就减少了出错的可能性。