zoukankan      html  css  js  c++  java
  • 第二十五章 面向对象------封装、内置函数、反射、动态导入

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

      

  • 相关阅读:
    C#深入浅出 修饰符(二)
    HDU 5785 Interesting
    HDU 5783 Divide the Sequence
    HDU 5781 ATM Mechine
    UVA 714 Copying Books
    uva 1471 Defense Lines
    UVA 11134 Fabled Rooks
    UVA 11572 Unique Snowflakes
    UVA 11093 Just Finish it up
    UVA 10954 Add All
  • 原文地址:https://www.cnblogs.com/sry622/p/10896914.html
Copyright © 2011-2022 走看看