zoukankan      html  css  js  c++  java
  • 封装

    一、什么是封装?

      封装就是指隐藏对象的属性和实现的细节,仅对外公开提供简单的接口。

    控制程序中属性的访问权限: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不推崇限制你的语法, 我们可以设计成鸭子类型,既让多个不同类对象具备相同的属性和方法

    对于使用者而言,就可以以不变应万变,轻松的使用各种对象

      

  • 相关阅读:
    工坊第五天
    工坊第四天
    工坊第三天
    工坊第二天
    工坊第一天
    莫队 优雅暴力出奇迹
    状压 DP 总结
    关于MatlabGUI清除WorkSpace的用法
    ArduinoNano卡在上传,无法烧录
    两轮差速驱动机器人的坐标轨迹计算
  • 原文地址:https://www.cnblogs.com/Gaimo/p/11252447.html
Copyright © 2011-2022 走看看