封装的含义
封装是指将数据与具体操作的实现代码放在某个对象内部,使这些代码的实现细节不被外界发现,外界只能通过接口使用该对象,而不能通过任何形式修改对象内部
封装的目的有三个:保护隐私、保证稳定性、降低使用复杂度
基本使用
class Student(object):__name = '这是隐藏的' # 在python中所以并没有真正的隐藏,而是自动转换成了特定的语法name = '这是没有隐藏的'def __init__(self):passprint(Student.__dict__)# '_Student__name': '这是隐藏的'obj = Student()print(obj.name)# 这是没有隐藏的print(obj.__name)# 报错# AttributeError: 'Student' object has no attribute '__name'# print(obj._Student__name) # 虽然也可以通过这个这方法访问到,但是我们这样写就是为了不要去直接访问,明白即可# 这是隐藏的# print(Student._Student__name) # 虽然也可以通过这个这方法访问到,但是我们这样写就是为了不要去直接访问,明白即可# 这是隐藏的
注意:
- 封装的功能只在类定义阶段才能生效
- 封装并不是绝对的,仅是做了语法上的变形而已
- 虽然指定了封装的内部变形语法,但是也不能直接去访问,需要通过特定的通道(接口)去访问
开放接口
class Student(object):__school = '清华大学'def __init__(self, name, age):self.__name = nameself.__age = age# 开设一个访问学生数据的通道(接口)def check_info(self):print("""学生姓名:%s学生年龄:%s""" % (self.__name, self.__age))# 开设一个修改学生数据的通道(接口)def set_info(self, name, age):if len(name) == 0:print("用户不能为空")returnif not isinstance(age, int):print("年龄必须是数字")returnself.__name = nameself.__age = agestu = Student('kevin', 22)stu.check_info()# 学生姓名: kevin# 学生年龄: 22stu.set_info('tony', 18)stu.check_info()# 学生姓名: tony# 学生年龄: 18stu.set_info('', 18)# 用户不能为空stu.set_info('kevin', '1')# 年龄必须是数字"""将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,接口之上可以附加额外的逻辑来对数据的操作进行严格地控制,目的的是为了隔离复杂度,例如:ATM程序的取款功能,该功能有很多其他功能组成,比如插卡、身份认证、输入金额、打印小票、取钱等,而对使用者来说,只需要开发取款这个功能接口即可,其余功能也可以隐藏起来。"""
property装饰器
property就是将方法伪装成数据
class Num(object):def __init__(self, num_1, num_2):self.num_1 = num_1self.num_2 = num_2@propertydef res(self):return "%s乘%s,结果等于%s" % (self.num_1, self.num_2, self.num_1 * self.num_2)num = Num(9, 6)print(num.res) # 不写@property,调用应该是num.res(),写上@property少了括号,伪装成数据
扩展
property还提供设置和删除属性的功能
class Student(object):def __init__(self, name):self.__name = name # 将属性隐藏起来@propertydef name(self):return self.__name # 将功能方法,伪装成数据@name.setterdef name(self, value):if not isinstance(value, str):print("%s,必须是字符串" % value)returnself.__name = valuereturn@name.deleterdef name(self):print("不能删除")stu = Student('kevin')print(stu.name)# kevinstu.name = 123print(stu.name)# kevinstu.name = 'tony'print(stu.name)# tonydel stu.name# 不能删除
