prerequisite: Python装饰器 在面向对象编程中,我们通常希望一个类的属性具有一定程度的封装性,其他对象只能通过定义好的接口访问这些属性,而不能够随意修改。Java里面体现在getter和setter两个方法。
在Python中如果我们不希望类的方法被修改,可以使用@Property
装饰器。它可以修饰方法,将该被修饰的方法转为相同名称的只读属性;也可以与属性配合使用,来防止属性被修改。
即@Property
装饰器常见使用场景有两个:
class Data:
@property
def printnum_with_property(self):
return 100
def printnum_without_property(self):
return 100
data = Data()
print(data.printnum_without_property())
print(data.printnum_with_property)
print(data.printnum_with_property())
结果:
100
100
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-58eda0e50ce8> in <module>
9 print(data.printnum_without_property())
10 print(data.printnum_with_property)
---> 11 print(data.printnum_with_property())
TypeError: 'int' object is not callable
注:一个方法被@property修饰之后,就变成了属性,不能在通过对象名.方法名()
访问到,只能是使用访问属性的方法即对象名.方法名
来访问。
class Data(object):
def __init__(self):
self._count = 100
@property
def count(self):
return self._count
data = Data()
print(data.count)
data.count = 200
print(data.count)
注:self._count
中的下划线可以不加,语法上也没有错误,但这种写法强调来_count
是类的一个固有属性,是推荐写法。
结果如下:
100
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-13-38f5dc4a3fc6> in <module>
9
10 print(data.count)
---> 11 data.count = 200
12 print(data.count)
AttributeError: can't set attribute
注:data._count
依然能被访问和更改。
class Data(object):
def __init__(self):
self._count = 100
@property
def count(self):
return self._count
data = Data()
print(data.count)
data._count = 200
print(data.count)
结果如下,不会报错:
100
200