封装、prorerty装饰器、python实现封装的原理等
封装:
将丑陋的复杂的隐私的细节隐藏到内部,对外提供简单的接口。对外隐藏实现的细节,并提供简单的接口。
为什么使用封装:
1、保证重要数据的安全性,即不希望被修改的数据。
2、对外隐藏内部细节,隔离复杂度
什么情况使用封装?
1、当一些数据不希望被外部修改的时候。
2、当一些函数不希望被外部调用的时候。
语法:
在属性或方法前面加上两个下划线
被封装的内容的特点:
1.外界不能直接访问
2、内部可以继续使用
外界访问私有内容的方式:
可以通过在内部定义方法的方式来实现
1 """ 2 这是一个下载器类,需要提供一个缓存大小这样的属性 3 缓存大小不能超过内存限制 4 5 """ 6 class Downloader: 7 def __init__(self,filename,url,buffer_size): 8 self.filename = filename 9 self.url = url 10 self.__buffer_size= buffer_size 11 12 def start_download(self): 13 if self.__buffer_size <= 1024*1024: 14 print("开始下载....") 15 print("当前缓冲器大小",self.__buffer_size) 16 else: 17 print("内存炸了! ") 18 19 20 def set_buffer_size(self,size): 21 #可以在方法中添加额外的逻辑 22 if not type(size) == int: 23 print("大哥 缓冲器必须是整型") 24 else: 25 print("缓冲区大小修改成功!") 26 self.__buffer_size = size 27 28 def get_buffer_size(self): 29 return self.__buffer_size 30 31 d = Downloader("葫芦娃","http://www.baicu.com",1024*1024) 32 33 34 # 通过函数取修改内部封装的属性 35 d.set_buffer_size(1024*512) 36 37 # 通过函数访问内部封装的属性 38 print(d.get_buffer_size()) 39 40 d.start_download()
prorerty装饰器:
通过方法来修改或访问属性,本身没什么问题,但是这给对象的使用者带来了麻烦.
使用必须知道哪些是普通属性,哪些是私有属性,需要使用不同的方式来调用他们
property装饰就是为了使得调用方式一致
有三个相关的装饰器
1.property 该装器用在获取属性的方法上
2.@key.setter 该装器用在修改属性的方法上
3.@key.deleter 该装器用在删除属性的方法上
注意:key是被property装饰的方法的名称 也就是属性的名称
内部会创建一个对象 变量名称就是函数名称
所以在使用setter和deleter时 必须保证使用对象的名称取调用方法
所以是 key.setter
1 class A: 2 def __init__(self,name,key): 3 self.__name = name 4 self.__key = key 5 6 @property 7 def key(self): 8 return self.__key 9 10 @key.setter 11 def key(self,new_key): 12 if new_key <= 100: 13 self.__key = new_key 14 else: 15 print("key 必须小于等于100") 16 17 18 @key.deleter 19 def key(self): 20 print("不允许删除该属性") 21 del self.__key 22 23 a = A("jack",123) 24 print(a.key) 25 a.key = 321 26 print(a.key)
python实现封装的原理:
python一般不会强制要求程序必须怎么怎么的
封装:
对外部隐藏内部的实现细节,并提供访问的接口
好处:
1.提高安全性
2.隔离复杂度
语法:将要封装的属性或方法名称前加上双下划线
访问被隐藏的属性:
提供用于访问和修改的方法
使用property装饰器可以将一个方法伪装成普通顺属性,保持属性之间调用方法一致
封装的实现原理 ,替换变量名称
抽象类:
指的是包含抽象方法(没有函数体的方法)的类,
作用:可以限制子类必须类中定义的抽象方法
最后:python一般不会限制你必须怎么写,作为一个优秀的程序员,就应该自觉遵守相关协议
所以有了鸭子类型这么一说:
如果这个对象长得像鸭子,走路像鸭子,那就他是鸭子
你只要保证你的类按照相关的协议类编写,也可以达到提高扩展性的目的
1 class Mouse: 2 def open(self): 3 print("鼠标开机.....") 4 5 def close(self): 6 print("鼠标关机了...") 7 8 def read(self): 9 print("获取了光标位置....") 10 11 def write(self): 12 print("鼠标不支持写入....") 13 14 15 16 def pc(usb_device): 17 usb_device.open() 18 usb_device.read() 19 usb_device.write() 20 usb_device.close() 21 22 m = Mouse() 23 # 将鼠标传给电脑 24 pc(m) 25 26 class KeyBoard: 27 def open(self): 28 print("键盘开机.....") 29 30 def close(self): 31 print("键盘关机了...") 32 33 def read(self): 34 print("获取了按键字符....") 35 36 def write(self): 37 print("可以写入灯光颜色....") 38 39 40 # 来了一个键盘对象 41 k = KeyBoard() 42 pc(k) 43 44 class UDisk: 45 def open(self): 46 print("U盘启动了...") 47 48 def close(self): 49 print("U盘关闭了...") 50 51 def read(self): 52 print("读出数据") 53 54 def write(self): 55 print("写入数据") 56 57 u = UDisk() 58 pc(u)
接口是一套协议规范,明确子类们应该具备哪些功能
抽象类是用于强制要求子类必须按照协议中规定的来实现
然而,python不推崇限制你的语法, 我们可以设计成鸭子类型,既让多个不同类对象具备相同的属性和方法
对于使用者而言,就可以以不变应万变,轻松的使用各种对象