9.5 特性
第7章提到了存取方法,它们是名称类似于getHeight和setHeight的方法,用于获取或设置属性(这些属性可能是私有的,详情请参阅7.2.4节)。如果访问给定属性时必须采取特定的措施,
那么像这样封装状态变量(属性)很重要。例如,请看下面的Rectangle类:
class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
def set_size(self, size):
self.width, self.height = size
def get_size(self):
return self.width, self.height
下面的示例演示了如何使用这个类:
>>> r = Rectangle()
>>> r.width = 10
>>> r.height = 5
>>> r.get_size()
(10, 5)
>>> r.set_size((150, 100))
>>> r.width
150
get_size和set_size是假想属性size的存取方法,这个属性是一个由width和height组成的元组。(可随便将这个属性替换为更有趣的属性,如矩形的面积或其对角线长度。)这些代码并非完全错误,但存在缺陷。使用这个类时,程序员应无需关心它是如何实现的(封装)。如果有一天你想修改实现,让size成为真正的属性,而width和height是动态计算出来的,就需要提供用于访问width和height的存取方法,使用这个类的程序也必须重写。应让客户端代码(使用你所编写代码的代码)能够以同样的方式对待所有的属性。
那么如何解决这个问题呢?给所有的属性都提供存取方法吗?这当然并非不可能,但如果有大量简单的属性,这样做就不现实(而且有点傻),因为将需要编写大量这样的存取方法,除了获取或设置属性外什么都不做。这将引入复制并粘贴(重复代码)的坏味,显然很糟糕(虽然在有些语言中,这样的问题很常见)。所幸Python能够替你隐藏存取方法,让所有的属性看起来都
一样。通过存取方法定义的属性通常称为特性(property)。
在Python中,实际上有两种创建特定的机制,我将重点介绍较新的那种——函数property,它只能用于新式类。随后,我将简单说明如何使用魔法方法来实现特性。
领取专属 10元无门槛券
私享最新 技术干货