• 第二十五章 面向对象------封装、内置函数、反射、动态导入


    1、封装

    什么是封装?

      1.对外部隐藏内部的属性,以及实现细节,给外部提供使用的接口

        注意:封装有隐藏的意思,但不是单纯的隐藏

        学习封装的目的:就是为了能够限制外界对内部数据的访问

      python中属性的权限分为两种:

      1.公开的

        没有任何限制,谁都可以访问

      2.私有的

        只有当前类本身能狗访问

      默认为公共的

    为什么要封装?

      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!")

    什么样的方法应该被封装起来?

      一个为内部提供支持的方法,不应该让外界直接访问,那就封装起来,如下例中的  user_auth

    class ATM:

      def withdraw(self):

        self.__user_auth()

        self.__input_money()

        self.__save_record()

        # 输入账号和密码
        # 显示余额
        # 输入取款金额
        # 保存记录

      def __user_auth(self):

        print('请输入账号密码...')

      def __input_money(self):

        print('余额为1000000000,请输入取款金额!')

      def __save_record(self):

        print('记录流水......')

    封装原理:

    python是通过 变形的方式来实现的封装
    如何变形 在名称带有双下划线开头的变量名字前添加_类名 如_Person__id_card
    当然通过变形后的名字可以直接访问被隐藏的属性 但通过不应该这么做
    变形仅在类的定义阶段发生一次 后续再添加的带有双下划线的任何属性都不会变形 就是普通属性

    什么时候用?

    封装属性:

      当这个对象存在一个机密性的属性,例:身份证信息,银行卡密码等,这样属性不应该被外界直接访问到时就将其封装。

    封装方法:

      一个为内部提供支持的方法,不应该让外界直接访问,那就将其封装。

    Prorety

    作用:将一个方法伪装成普通属性;用property是为了希望将访问私有属性和普通属性的方式变得一致。

    与Prorety相关的两个装饰器:

    setter:用 . (点)语法给属性赋值是触发

    deleter:用 . (点)语法删除属性时触发

    例:

    calss Teacher:

      def __init__(self,name,age.salary):

        self.name=name

        self.age=age

        self.__salary=salary

      @property  # getter   # 用于访问私有属性的值   也可以访问普通属性

      def salary(self):

        return self.__salary

      @salary.setter  # 用来设置私有属性的值  也可以设置普通属性

      def salary(self):

        self.__salary=new_salary

      @salary.deleter   # 用来设置私有属性的值  也可以删除普通属性

        # print("can not delete salary!")

        del  self.__dict__['Teacher__salary']

    Property 计算属性使用场景:

    什么是计算属性:

      一个属性它的值不是固定死的,而是通过计算动态产生的。

    class Person:

      def __inin__(self,name,height,weight):

        self.name=name

        self.height=height

        self.weight=weight

      @aproperty

      def  BMI(self):

         return sdlf.weight/(self.height**2)

      @setter

      def  BMI(self,new_BMI):

        print('BMI 不支持自定义......')

    p=person('egon',1.7,80)

    print(p.BMI)

    P.BMI=10

    多态: 多态不是一个具体的技术或代码,指的是,多个不同类型对象,可以响应同一个方法,产生不同结果

    使用多态的好处:

      只需要学习积累中的使用方法即可,不需要关心具体的哪一个类,实现  

       以不变应万变  提高灵活性  提高扩展性

      如果没有多态,需要分别学习 person cat pig 的不同使用方法,这对于使用者而言太麻烦了

      鸭子类型:就是典型的多态,多重不同类型 使用方法一样

    案例:

    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__

    对象转成字符串是被强制执行

    __del__

    __del__:当对象被删除前会自动调用 ,该方法声明时候会删除对象?

        1.程序运行结束,解释器退出,将自动删除所有数据

        2.手动调用del 时也会删除对象

        注意:该函数不是用来删除对象的

    使用场景:

      当你的对象在创建时,开启了不属于解释器的资源,例如打开一个文件必须保证对象被删除时,

    同时关闭额外的资源,如文件。

    __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()

    反射(英文中叫反省,自省)

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

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

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

    涉及到方法:

    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....!")

     

    动态导入模块

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

      

  • 相关阅读:
    关于Entity Framework中的Attached报错的完美解决方案
    关于C# Winform DataGridView 设置DefaultCellStyle无效的原因与解决方案
    实现winform DataGridView控件判断滚动条是否滚动到当前已加载的数据行底部
    关于Entity Framework自动关联查询与自动关联更新导航属性对应的实体注意事项说明
    阅读《LEARNING HARD C#学习笔记》知识点总结与摘要系列文章索引
    阅读《LEARNING HARD C#学习笔记》知识点总结与摘要五
    C# Winform 通过FlowLayoutPanel及自定义的编辑控件,实现快速构建C/S版的编辑表单页面
    NPOI导入导出EXCEL通用类,供参考,可直接使用在WinForm项目中
    阅读《LEARNING HARD C#学习笔记》知识点总结与摘要四
    C#实现通用数据过滤窗体
  • 原文地址:https://www.cnblogs.com/sry622/p/10896914.html
Copyright © 2020-2023  润新知