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 即导入成功的模块
    该方式常用在框架中 因为框架设计者不可能提前预知后续需要的模块和类

  • 相关阅读:
    How to change hostname on SLE
    How to install starDIct on suse OS?
    python logging usage
    How to reset password for unknow root
    How to use wget ?
    How to only capute sub-matched character by grep
    How to inspect who is caller of func and who is the class of instance
    How to use groovy script on jenkins
    Vim ide for shell development
    linux高性能服务器编程 (二) --IP协议详解
  • 原文地址:https://www.cnblogs.com/WBaiC1/p/10896715.html
Copyright © 2011-2022 走看看