# 将复杂的丑陋的隐私的细节隐藏到内部,对外提供简单的使用接口 或 # 对外隐藏内部实现细节,并提供访问的接口
为什么需要封装1.为了保证关键数据的安全性
2.对外部隐藏内部的实现细节,隔离复杂度
什么时候需要封装:# 当有一些数据不希望外界可以直接修改时,# 当有一些函数不希望给外界使用时
如何使用封装语法:(给属性或者方法前面加上 __ 双下划线,外界就访问不到了)
用户的身份证号等信息属于用户的隐私,肯定不能直接暴露给外界可以直接访问或修改,那么就不能把它作为普通属性了,应该是私有属性
class Person: def __init__(self, id_number, name, age): # 身份证号码肯定不能随便改!那就需要给他隐藏起来(__属性,隐藏起来) self.__id_number = id_number # ************ 把属性隐藏起来 # self.id_number = id_number self.name = name self.age = age def show_id(self): print(self.__id_number) def __say_hi(self): print(f"hi, 我是{self.name}") p = Person('111111111111111111', 'jack', 29) p.id_number = '222' # 这里其实是给对象加了个属性 id_number(对象属性的增删改查) print(p.id_number) # 222 p.show_id() # 111111111111111111 # 并没有受到影响 # p.__id_number # 报错,pycharm没有提示也找不到,AttributeError: 'Person' object has no attribute '__id_number' # p.__say_hi # 报错,AttributeError: 'Person' object has no attribute '__say_hi'封装方法案例
用户使用电脑只需要按下开机键即可,具体开机要涉及检查硬件啊、载入内核、初始化内核等操作,用户根本不需要去操作,也不需要去了解(不然还得学,那用个电脑这么麻烦,估计是不用了),况且没有接通电源是无法载入内核的(有先后顺序),此时就可以把载入内核等方法封装起来,作为私有方法,在暴露出来的接口中调用,这样用户只需要按下开机即可完成了。
class PC: def __init__(self, price, kind, color): self.price = price self.kind = kind self.color = color # 外部只需要调用这个open 就可以启动电脑了,其他的歩鄹都不需要外界操作 def open(self): # 复杂的开机流程 print("接通电源") self.__check_device() print("载入内核") print("初始化内核") self.__start_services() print("启动GUI") self.__login() # 必须先接通电源 @staticmethod # def check_device(): def __check_device(): print("硬件检测1") print("硬件检测2") print("硬件检测3") print("硬件检测4") # 必须先接通电源 @staticmethod # def start_services(): def __start_services(): print("启动服务1") print("启动服务2") print("启动服务3") print("启动服务4") # 必须先启动了才能登录 --> 不能让外界直接调用登录 @staticmethod # def login(): def __login(): print("login流程1.......") print("login流程2.......") print("login流程3.......") print("login流程4.......") pc = PC(5688, 'ASUS', 'black') pc.open() # 一键启动 # 接通电源 # 硬件检测1 # 硬件检测2 # 硬件检测3 # 硬件检测4 # 载入内核 # 初始化内核 # 启动服务1 # 启动服务2 # 启动服务3 # 启动服务4 # 启动GUI # login流程1....... # login流程2....... # login流程3....... # login流程4....... 被封装内容的特点外界不能直接访问
类内部依然可以使用
权限利用好封装的特性就可以控制属性的权限(接着往下看)
python中只有两种权限公开的(默认就是公开的)
私有的,只能由当前类自己使用
在外界访问私有内容可以通过封装非私有方法来实现(类内部还是可以访问自身的私有属性的)
''' 这是一个下载器类,需要提供一个缓存大小这样的属性 缓存大小不能超过内存限制 ''' class Downloader: def __init__(self, filename, url, buffer_size): self.filename = filename self.url = url # self.buffer_size = buffer_size self.__buffer_size = buffer_size # 一旦被私有后,外界就无法直接访问了,应该给外界提供一个接口,可以改动 def start_download(self): # if self.buffer_size <= 1024*1024: if self.__buffer_size <= 1024*1024: print("开始下载...") else: print("内存超过限制!") # 可以在方法中添加一些额外的逻辑 def set_buffer_size(self, size): # 这里可以加一些限制操作,限制大小或者登录验证,数据校验 if not isinstance(size, int): print("缓冲区大小必须是整数!") return False self.__buffer_size = size def get_buffer_size(self): return self.__buffer_size d = Downloader("冰火两重天", 'https://www.baidu.com', 1024*1024) # d.buffer_size = 1024*1024*1024 d.start_download() # 开始下载... d.set_buffer_size(1024 * 512) # 外界通过方法改动私有属性 d.set_buffer_size('aa') # 外界通过方法改动私有属性 # 缓冲区大小必须是整数! d.start_download() # 开始下载... print(d.get_buffer_size()) # 外界通过方法访问私有属性 # 524288 d.set_buffer_size(1024 * 1024 * 1024 / 2) # 这里 / 2 变成了float 浮点型,类型不匹配了 # 缓冲区大小必须是整数! d.start_download() # 开始下载... # 这里用的是之前的buffer_size,上面没有改成功(不然超出大小了也下不了的) d.set_buffer_size(1024 * 1024 * 1024) # set_buffer_size() 里没有做大小限制,所以其实是改成功了 d.start_download() # 超过大小限制,所以提示内存超过限制 # 内存超过限制!好处:通过封装的方法来修改、读取、删除(私有)属性,可以在对属性进行修改、读取、删除的时候可以做拦截,做一些逻辑操作