封装
一、什么是封装?
封装就是指隐藏对象的属性和实现的细节,仅对外公开提供简单的接口。
控制程序中属性的访问权限:Python中权限分为两种:
1:公开 外界可以直接访问和修改
2:私有 外界不能直接访问和修改,在当前类中可以直接修改和访问
二、为什么要封装,有什么好处?
1、为了保护数据的安全 (身份证信息,银行卡密码等)
2、对外隐藏实现的细节,为了隔离复杂度 (电脑的开机功能,手机的使用不需要考虑如何实现等)
三、什么时候应该使用封装:
当有一些数据不希望外界可以直接修改时: 当有一些函数不希望给外界使用时
四、封装的语法:
在属性名前添加两个下划线__ 将其设置为私有的
语法和应用场景: 外界不能直接访问,内部依然可以使用
class Person: def __init__(self,name,age,id_number): self.__id_number=id_number # 封装起来 变为私有 self.age=age self.name=name p = Person("5272219544082421124","Gavin",20) p.id_number="15464487648" print(p.id_number) print(Person.__dict__) >>> 15464487648 {'__module__': '__main__', '__init__': <function Person.__init__ at 0x000001D3B65D57B8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
五、在外界访问私有的内容
属性虽然被封装了,但是还是需要使用的,在外界如何访问?
可以通过 定义类完成对私有属性对的修改和访问
""" 这是一个下载器类,需要提供一个缓存大小这样的属性 缓存大小不能超过内存的极限 """ class Downloader: # 定义一个类 def __init__(self,filename,url,buffer_size): #定义属性 self.filename=filename self.url=url self.__buffer_size=buffer_size # 初始化封装数据 def start_downloader(self): #开始下载 if self.__buffer_size<=1024*1024: # 添加条件判断 print("开始下载.....") print("当前的缓存器大小为",self.__buffer_size) else: print("内存要炸了,谨慎!!") # 可以通过定义类完成对私有属性对的修改和访问 def set_buffer_size(self,size): # 函数 获取__中的下载缓存的大小并修改 if not type(size)==int: print("对不起,缓存的数据必须是整型的") else: print("缓存区的大小修改成功!") self.__buffer_size=size def get_buffer_size(self): # 获取缓存的数据大小 return self.__buffer_size d=Downloader("我是谁,没有绝对安全的系统","https//www.baidu.com",1024*1024) d.set_buffer_size(1024*60) # 修改下载缓存的大小 print(d.get_buffer_size()) d.start_downloader() # 通过修改类之后可以访问是私有的数据 # 修改后都可以获取数据 d.set_buffer_size(1024*6) d.get_buffer_size() d.start_downloader()
六、封装之property
1、什么是:property ?
property是一个装饰器,将一个方法伪装成普通的属性,其特殊之处在在于,该方法会在修改属性值时自动执行
2、为什么要用property?
通过方法来修改或访问属性,本身没什么问题,但是这给对象的使用者带来了麻烦,
使用必须知道哪些是普通属性,哪些是私有的属性,需要使用不同的方式来调用他们;
property装饰器就是为了使得他们的调用方式统一(用统一的调用方式)
有三个相关的装饰器:
1、property 该装器用在获取属性的方法上
2、@key.setter 该装器会在修改属性值时自动执行
3、@key.deleter 该装器会在删除属性值自动执行
class A: def __init__(self,name,key): self.__name=name # 全部封装 self.__key=key @property # 用该装饰器然私有的属性转化为普通法的属性 def key(self): return self.__key @key.setter #调用该装饰器修改属性 def key(self,new_key): if new_key <=100: self._key=new_key else: print("key 必须小于等于100") @key.deleter # 删除 属性内容 def key(self): print("不允许删除该属性") del self.key print(self.key) a=A("James",986059) print(a.key) a.key=123 print(a.key)
注意 :key是被property装饰的方法的名称 也就是属性的名称
内部会创建一个对象 变量名称就是函数名称,所以在使用setter和deleter时,必须保证使用的名称取调用方法
所以是key.stter
七、property可以用来实现属性的计算:
计算属性的值指的是:属性的值,不能直接获取,必须通过计算才能获取
例如:正方形求面积:
class Square: def __init__(self,width): self.width=width @property # 让属性装换为普通类 def area(self): return self.width*self.width s=Square(10) print(s.area) s.width=20 print(s.area) s.width=2 print(s.area) >> E:\PY\venv\Scripts\python.exe E:/PY/封装.py 100 400 4
八、Python实现封装的原理
就是在加载类的时候把__替换成了_类名_,Python一般不会强制要求程序员必须怎么怎么的,所以一般默认不更改
类在加载时默认把__给更改了,而且只改一次
九、接口 (了解)
接口是一组功能的集合体,但是接口中仅包含功能的名字,不包含具体的实现代码;
接口的本质是一套协议标准,遵循这个标准的对象就能被调用
接口的目的就就是为了提高扩展性:
例如:电脑提前指定一套USB接口协议,只要你遵循该协议,你的设备就可以被电脑使用,不需要关系到底是 鼠标还是键盘
class USB: def open(self): pass def close(self): pass def read(self): pass def write(self): pass class Mouse(USB): def open(self): print("鼠标开机.....") def close(self): print("鼠标关机了...") def read(self): print("获取了光标位置....") def write(self): print("鼠标不支持写入....") def pc(usb_device): usb_device.open() usb_device.read() usb_device.write() usb_device.close() m = Mouse() # 将鼠标传给电脑 pc(m) class KeyBoard(USB): def open(self): print("键盘开机.....") def close(self): print("键盘关机了...") def read(self): print("获取了按键字符....") def write(self): print("可以写入灯光颜色....") # 来了一个键盘对象 k = KeyBoard() pc(k)
接口主要是方便了对象的使用者,降低使用者的学习难度,只要学习了一套使用方法,就可以以不变应万变
十、抽象类(了解):
import abc
abstract class
翻译为抽象类
抽象类的定义 :
类中包含 没有函数体的方法
指的是包含抽象方法(没有函数的方法)的类
class person: def run(self): pass # 函数体中没有方法 这种就叫抽象类
作用:可以实现强制性要求子类必须实现父类声明的方法
抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化,且有存在没有实现的方法;
import abc class AClass(metaclass=abc.ABCMeta): @abc.abstractmethod def run(self): pass @abc.abstractmethod def run1(self): pass class B(AClass): def run(self): print("runrunrurn...") b = B()
十一、鸭子类型(了解)
Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’
python比较随意不会限制程序员如何去编写程序,但作为合格的程序员就必须自觉遵守相关协议(接口)
就是要保证你的类按照相关的协议类编写,也可以达到提高扩展性的目的
小结:
接口是一套协议规范,明确子类们应该具备哪些功能
然而,python不推崇限制你的语法, 我们可以设计成鸭子类型,既让多个不同类对象具备相同的属性和方法
对于使用者而言,就可以以不变应万变,轻松的使用各种对象
本文来自博客园,作者:游走De提莫,转载请注明原文链接:https://www.cnblogs.com/Gaimo/p/11252447.html