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