属性的使用

面向对象的语言一般都支持私有字段,这部分字段不能从对象外部直接访问。但是Python中所有字段都是公开的,即public的。所以Python中有一条惯例:使用双下划线标记的字段为私有字段,不能从对象外部及其子类中直接访问,即__name形式的字段,私有字段在类内部也要使用self.__name的形式访问。同理,私有方法则是在方法名前增加两条下划线,即def __private_method();如果需要允许在子类中访问指定属性或方法,则需要使用单下划线语法,即_namedef _protected_method()

这种私有内容的表示方法虽然是约定惯例,但目前Python的解释器已经将其实装并在出现非法访问时会提示错误。

要对私有字段进行访问,Python提供了属性这个特性。可以允许为对象编写getter和setter方法来组成对类内部字段的操作。下面通过一个示例来说明属性的定义方法。

def Person:
	__name = ''
	
	def __init__(self, name):
		self.__name = name
	
	def get_name(self):
		return self.__name
	
	def set_name(self, name):
		self.__name = name
	
	name = property(get_name, set_name)

h = Person('Howard')
print(h.name)
h.name = 'Lynn'
print(h.name)

示例中的get_name()set_name()都是可以直接调用的,最后一个property()的定义将两者结合了起来形成了一个属性。

另一种定义属性的方式是使用修饰符。使用修饰符定义属性设计两个修饰符的使用:@property@propertyName.setter。这里需要使用定义的属性名称替换propertyName

下面用修饰符重新定义上面的示例。

def Person:
	__name = ''
	
	def __init__(self, name):
		self.__name = name
	
	@property
	def name(self):
		return self.__name
	
	@name.setter
	def name(self, name):
		self.__name = name

这种定义已经不像前面那一种一样需要两个显式的getter和setter方法了。这里的属性使用同一个名称但有两个不同重载的方法组成,并且包含不同的修饰符。属性的名称默认是@property修饰符修饰的方法名称。

除了可以对类内部的私有字段进行操作以外,属性还可以用来获取动态产生的计算结果值,即计算属性。如果没有定义setter属性,那么使用@property定义的属性即成为只读属性。