zoukankan      html  css  js  c++  java
  • day26,封装,多态,内置函数,反射

                                                              封装,多态,内置函数,反射

    封装

    什么是封装:

      一个为内部提供支持的方法或者属性,不应该让外界直接访问,那就封装起来,这就是封装

    封装的原理:

      python是通过 变形的方式来实现的封装

      如何变形 在名称带有双下划线开头的变量名字前添加_类名 如_Person__id_card

      当然通过变形后的名字可以直接访问被隐藏的属性 但通过不应该这么做

      变形仅在类的定义阶段发生一次 后续再添加的带有双下划线的任何属性都不会变形 就是普通属性

    封装的好处:

      1.提高安全性

           封装属性

      2.隔离复杂度

           封装方法

    封装属性:

    class Student:
    
        def __init__(self,name,age,gender,id_card):
            self.name = name
            self.age = age
            self.gender = gender
            self.__id_card = id_card
    
        def show_id_card(self):
            # 可以在这里添加额外的任何逻辑代码 来限制外部的访问
            
            #在类的内部 可以访问
            print(self.__id_card)

    对私有属性的访问以及修改

    class Student:
        def __init__(self,name,age,gender,id_card):
            self.name = name
            self.age = age
            self.gender = gender
            self.__id_card = id_card
    
        # 访问被封装的属性  称之为访问器
        def get_id_card(self,pwd):
            # 可以在这里添加额外的任何逻辑代码 来限制外部的访问
            # 在类的内部 可以访问
            if pwd =="123":
                return self.__id_card
            raise Exception("密码错误!")
    
    
        # 修改被封装的属性   称之为设置器
        def set_id_crad(self,new_id):
            # 身份证必须是字符串类型
            # 长度必须是18位
            if isinstance(new_id,str) and len(new_id) == 18:
                self.__id_card = new_id
            else:
                raise Exception("身份证号码 必须是字符串 且长度必须为18!")

    Property

    作用: 将一个方法伪装成普通属性

    为什么用 property 希望将访问私有属性和普通属性的方式变得一致

    与property相关的 两个装饰器

    setter

          用点语法 给属性赋值时触发

    deleter

          用点语法删除属性时触发

    class Person:
        def __init__(self,name,age,gender,id_card):
            self.name = name
            self.age = age
            self.gender = gender
            self.__id_card = id_card
        @property
        def id_card(self):
            return self.__id_card
        @id_card.setter
        def id_card(self,new_id_card):
            self.__id_card = new_id_card
    
        @id_card.deleter
        def id_card(self):
           del  self.__id_card
    
    # p = Person("rose",19,"woman","123455467")
    #获取私有的属性
    # print(p.id_card)
    #修改私有的属性
    # p.id_card = "1234567890"
    # print(p.id_card)
    
    #删除一个私有的属性
    # del p.id_card
    
    # print(p.id_card)
    
    class User:
    
        def __init__(self,name,height,weitght):
            self.name = name
            self.height = height
            self.weitght = weitght
            # self.BMI = height/(weitght**2)
        @property
        def BMI(self):
            return self.height/(self.weitght**2)
    
        @BMI.setter
        def BMI(self,new_bmi):
            print("不能被修改!")
    
    u = User("老男孩",170,60)
    print(u.BMI)
    u.weitght = 70
    print(u.BMI)
    #不能修改计算属性,计算属性是通过计算得来的,不是复制得来的
    u.BMI = 90
    View Code

    多态 

    什么是多态:

    多态不是一个具体的技术 或代码

    指的是 多个不同类型对象 可以响应同一个方法 ,产生不同结果

    多态的带来的好处:
    只需要学习基类中的使用方法即可, 不需要关心具体的哪一个类 以及实现的 以不变应万变 提高了灵活性
    提高扩展性

    如何实现多态:
    鸭子类型 就是典型的多态 多种不同类型 使用方法一样

    class Cat():
    def bark(self):
    print("喵喵喵")
    def run(self):
    print("四条腿跑!")
    def sleep(self):
    print("趴着睡!")
    
    class Pig():
    def bark(self):
    print("哼哼哼!")
    def run(self):
    print("四条腿跑!")
    def sleep(self):
    print("侧躺着睡!")
    
    # 一个用来管理动物的方法 只要你传入是一个动物 我就按照动物的标准来使用 完全不用考虑你具体是什么类型
    def management_animal(animal):
    print("==================正在溜%s=============" % animal.__class__.__name__)
    animal.bark()
    animal.run()
    animal.sleep()

    总结多态和封装重点

    封装

    什么是封装 *****

    封装的好处 *****

    如何封装

    封装的原理

    多态:

    多态指的是 多个不同类型对象可以响应同一个方法产生不同的结果 *****

    好处

    好处: 只需要学习基类中的使用方法即可, 不需要关心具体的哪一个类 以及实现的 以不变应万变 提高了灵活性
    提高扩展性

    常用的内置函数

    __str__

    class Person:
    
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __str__(self):
            print("执行str 函数")
    
    p = Person("rose",18)
    p.__str__()
    # print(p)

    __del__

    当对象被删除前会自动调用 该方法
    声明时候会删除对象?
        1.程序运行结束 解释器退出 将自动删除所有数据
        2.手动调用del 时也会删除对象
    
    注意:该函数不是用来删除对象的
    
    使用场景
    当你的对象在创建时,开启了不属于解释器的资源 例如打开了一个文件
    必须保证当对象被删除时 同时关闭额外的资源  如文件
    
    也称之为析构函数  构造 的反义词
        构造 指的是从无到有
        析构 值从有到无
        简单的说就对象所有数据全部删除
    
    总结:__del__该函数 用于 在对象删除前做一些清理操作
    class Person:
        def __init__(self,name,path,mode="rt",encoding="utf-8"):
            self.name = name
            self.file = open(path,mode,encoding=encoding)
    
    
    
        # 读取数据的方法
        def read_data(self):
            return self.file.read()
    
    
        def __del__(self):
            print("del run!")
            self.file.close()
    View Code

    反射

    英文中叫反省 (自省)

    面向对象中的反省 指的是,一个对象必须具备,发现自身属性,以及修改自身属性的能力;

    一个对象在设计初期,可能考虑不够周全后期需要删除或修改已经存在的属性, 和增加属性

    反射就是通过字符串来操作对象属性

    涉及到的方法

    hasattr 判断是否存在某个属性

    getattr 获取某个属性的值

    setattr 新增或修改某个属性

    delattr 删除某个属性

    案例:

    class MY_CMD:
    
        def dir(self):
            os.system("dir")
    
        def ipconfig(self):
            os.system("ipconfig")
    
    cmd = MY_CMD()
    
    while True:
        name = input("请输入要执行的功能:")
        if hasattr(cmd,name):
            method = getattr(cmd,name)
            print(method)
            method()
        else:
            print("sorry this method is not exists....!")

    动态导入模块

    #D:pyproday26多态封装动态导入模板core.py
    import importlib
    from 动态导入模板 import conf
    
    def run():
        for path in conf.decorations:
            pathName,className = path.rsplit(".",1)
            mk = importlib.import_module(pathName)
            if not hasattr(mk,className):
                return
    
            obj = getattr(mk,className)
            o = obj()
            # print(o)
            o.run()
    run()
    
    #D:pyproday26多态封装动态导入模板conf.py
    decorations = [
        "动态导入模板.my_decoration.Table",
        "动态导入模板.my_decoration.Light",
        "动态导入模板.my_decoration.Bed",
    ]
    
    #D:pyproday26多态封装动态导入模板my_decoration.py
    class Table:
        def run(self):
            print("装修桌子好了")
    
    class Light:
        def run(self):
            print("装修灯好了")
    class Bed:
        def run(self):
            print("装修床好了")


    直接写import 称之为静态导入 建立在一个基础上:提前已经知道有这个模块
    动态导入 指的是 在需要的任何时候 通过指定字符串类型的包名称来导入需要的模块
    import importlib
    mk = importlib.import_module(m_name)
    mk 即导入成功的模块
    该方式常用在框架中 因为框架设计者不可能提前预知后续需要的模块和类

  • 相关阅读:
    TypeScript学习笔记
    Spring基础知识
    Filter基础知识
    如何开发自定义标签
    会话和会话状态
    Servlet转发到JSP页面的路径问题
    JDBC相关知识
    gimp 很强大, 可是不会用
    python 启动文件
    minidnla policy
  • 原文地址:https://www.cnblogs.com/WBaiC1/p/10896715.html
Copyright © 2011-2022 走看看