封装通常是对成员变量(实例变量和类变量)进行的封装。
在严格意义上的面向对象设计中,一个类是不应该有公有的实例成员变量的,这些实例成员变量应该被设计为私有的,然后通过共有的setter和getter访问器访问。
class Animal(object):
"""定义动物类"""
def __init__(self, age, sex=1, weight=0.0):
self.age = age
self.sex = sex
self.__weight = weight
def set_weight(self, weight):
self.__weight = weight
def get_weight(self):
return self.__weight
a1 = Animal(2, 0, 10.0)
print('{0:0.1f}'.format(a1.get_weight()))
a1.set_weight(1000)
print(a1.get_weight())
``
set_weight()
方法是setter访问器,参数用来替换现有成员变量。
访问器形式的封装需要一个私有变量,需要提供getter访问器和一个setter访问器,只读变量不用提供setter访问器,总之访问器形式的封装在编写代码的时候比较麻烦,为了解决这个问题,Python提供了属性(property),定义属性可以使用@property
和@属性名.setter()
装饰器
@property
用来修饰getter访问器
@属性名.setter()
用来修饰setter访问器
class Animal(object):
"""定义动物类"""
def __init__(self, age, sex=1, weight=0.0):
self.age = age # 实例成员变量
self.sex = sex
self.__weight = weight
@property
def weight(self):
return self.__weight
@weight.setter
def weight(self, weight):
self.__weight = weight
a1 = Animal(2, 0, 10.0)
print('{0:0.1f}'.format(a1.weight))
a1.weight = 1000
print(a1.weight)
属性本质上就是两个方法,在方法前加上装饰器使得方法成为属性,使用起来类似于公有变量
定义属性的时候,应该先定义getter访问器,再定义setter访问器。否则会出现错误