封装的含义
封装是指将数据与具体操作的实现代码放在某个对象内部,使这些代码的实现细节不被外界发现,外界只能通过接口使用该对象,而不能通过任何形式修改对象内部
封装的目的有三个:保护隐私、保证稳定性、降低使用复杂度
基本使用
class Student(object):
__name = '这是隐藏的' # 在python中所以并没有真正的隐藏,而是自动转换成了特定的语法
name = '这是没有隐藏的'
def __init__(self):
pass
print(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 = name
self.__age = age
# 开设一个访问学生数据的通道(接口)
def check_info(self):
print("""
学生姓名:%s
学生年龄:%s
""" % (self.__name, self.__age))
# 开设一个修改学生数据的通道(接口)
def set_info(self, name, age):
if len(name) == 0:
print("用户不能为空")
return
if not isinstance(age, int):
print("年龄必须是数字")
return
self.__name = name
self.__age = age
stu = Student('kevin', 22)
stu.check_info()
# 学生姓名: kevin
# 学生年龄: 22
stu.set_info('tony', 18)
stu.check_info()
# 学生姓名: tony
# 学生年龄: 18
stu.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_1
self.num_2 = num_2
@property
def 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 # 将属性隐藏起来
@property
def name(self):
return self.__name # 将功能方法,伪装成数据
@name.setter
def name(self, value):
if not isinstance(value, str):
print("%s,必须是字符串" % value)
return
self.__name = value
return
@name.deleter
def name(self):
print("不能删除")
stu = Student('kevin')
print(stu.name)
# kevin
stu.name = 123
print(stu.name)
# kevin
stu.name = 'tony'
print(stu.name)
# tony
del stu.name
# 不能删除