Python里的property

Python内置了一个property属性和property()函数,通过使用property我们可以更方便地访问类属性的值,它可以把调用方法转化为对实例属性直接的访问,既避免了属性的暴露,也不用调用setter方法和getter方法。

获取一个类的属性值,通常我们会编写一个setter方法用来设定值,一个getter方法用以获取值。

先看一般方法

定义一个People类,只有一个 name 属性, 接着定义People 的setter和getter方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class People():
def __init__(self, name):
self._name = name
def setName(self, name):
self._name = name
def getName(self):
return self._name
def main():
p = People("Jim")
print("The name is : " + p.getName())
p.setName("Tom")
print("The changed name is: " + p.getName())
if __name__ == '__main__':
main()
output: The name is : Jim
The changed name is: Tom

使用@property装饰器

通过@property可使一个方法变成属性,如下面代码中的name 方法,使用@property后可使其变成类的name 属性。同时@property 又生成了@name.setter,用以生成setter方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class People():
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
def main():
p = People()
p.name = "Tom" //实际上相当于settName()
print("The changed name is: " + p.name) //调用getName()
if __name__ == '__main__':
main()

使用property()函数

函数原型为 property(fget=None,fset=None,fdel=None,doc=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class People():
class People():
def __init__(self, name):
self._name = name
def setName(self, name):
self._name = name
def getName(self):
return self._name
name = property(setName, getName, None, None)
def main():
p = People()
p.name = "Tom"
print("The changed name is: " + p.name)
if __name__ == '__main__':
main()

我们看到,只需要在最后加上一行代码 name = property(setName, getName, None, None) ,就可以实现之前的功能。使用property()的好处是,它几乎没有破坏原有的代码。