python学习 第7周知识回顾总结(面向对象和类)

171 阅读7分钟

对象

  • 对象
    • 数据和功能的结合体,用于记录多个对象不同的数据和功能
  • 对象独有的数据
    • 往对象内添加该对象与众不同的数据
      • 1.利用__dict__方法朝字典添加键值对
      self1 = Student() 
      self1.__dict__['name'] = 'jack'
      print(self1.name)
        缺点:代码冗余,效率低下,添加一次就要输入一次
      
      • 2.封装为函数,添加独有的代码
      def init(self,name) 
          self.__dict__['name] = name 
      stu0 = Student()
      init(stu0,'tom')
      print(stu0.__dict__)
        缺点:每添加一次要重新用一个变量名,麻烦
      
      • 3.面对对象思想。使用init函数创建独有数据,将数据功能整合
      1.先产生一个空对象 
      2.调用类里的__init__方法,把产生空对象当作第一个参数传入 
      3.将产生的对象返回出去
          class Student: 
              def __init__(self, name): 
                  self.name = name 
              school = '清华大学' 
              def choice_course(self): 
                  print('正在选课') 
          stu1 = Student('jason') 
          print(stu1) 
          stu2 = Student('kevin') 
          print(stu2)
      
  • 对象独有的功能
针对对象独有的方法,我们无法实现: 
    1.方法如果在全局里则不是独有的
    2.方法如果在设置在类中也是公共的(谁都可以调) 
所以python解释器为了解决此问题: 
    将定义在类中的函数默认绑定给对象(变为独有的方法) 
    
class Person: 
    h_type = '人类' 
        # 让对象拥有独有的数据,这里独有的数据就是用户的名字 
    def __init__(self,name): 
        self.name = name 
       # 定义在对象里的类,称为方法 
       # 是多个对象独有的公共方法,对象来调用就会将对象本身当作第一个参数传入 
    def work(self): 
        print('%s正在写代码'%self.name)
    def others(self,a,b): 
        print('其他人的工作完成了')

  • 动静态方法
    • 动静态方法是专门针对写在类体代码中的函数
      • 绑定给对象的方法(直接在类体代码中编写)
        1.对象调用自动将对象当作第一个参数传进去
        2. 2.类的调用有几个形参就要传入相对于的实参
        
      • 绑定给类的方法(静态方法【普通的函数】)

面向对象

  • 面向对象:
    • 不同类型函数调用不同功能的过程就是面向对象
  • 面向对象编程:
    • 将数据和功能绑定到一起的操作
    • 本质:只能彼此相互使用
  • 面向对象编程思想:
    • 对象是核心,提供了解决问题的方法
    面向过程编程就是按流程办事得到结果,二者无优劣之分,经常混合使用。
    

面向对象的三大特性

继承

  • 含义:
    • 用来描述类与类之间数据的关系,类A继承了类B(拥有了类B里面所有的数据和功能)
  • 目的:
    • 为了节省代码的编写,可以继承一个类,也可以继承多个类
  类的继承关系: 平时最常用的就是父类或者子类
     被继承的类,我们称为,父类,基类或超类
     继承了类的类,我们称为,子类或派生类  
  怎样实现:
     class 类名1(类名2): 
         pass 
   1.定义类的时候要在类名1后面加括号 
   2.括号类名2里写的是要继承的类名 
   3.括号里可以继承多个父类,用逗号隔开 
   4.在括号里面,从左向右查找每个父类的属性
  • 本质:
抽象:
    将多个类共同的数据或功能抽取出来形成一个基类
继承:
    从上往下收容各个基类里的资源
对象与类的区别
    1.对象是数据和功能的结合体
    2.类是多个对象相同的数据和功能的结合体
    3.父类是多个类相同的数据和功能的结合体


   # 类与父类主要的功能是为了节省代码

  • 数据和方法找顺序
 不继承
     先从对象自身查找,没有再去产生对象的类中查找(对象>>>类)
 单继承
     先从对象自身查找,产生对象的类中查找,然后是一个个父类(对象>>>类>>>父类)
 多继承
     非菱形继承:  深度优先(单个分支走到底,在切换分支走到底)
     菱形继承:    广度优先(先走单个分支,遇到分支汇总不走,走其他分支,最后再走汇总的分支)
    
    
    (对象>>>类>>>父类)

封装

  • 目的
    • 把数据或功能隐藏,无法通过句点符点出来,然后通过特定接口才能访问
  • 本质
    • 在接口出添加了一些额外的操作,做了处理
  • property伪装属性
    • 将方法伪装为数据,可以点出来 property
    @property # 将一个函数伪装为一个属性,让人看起来更加合理
    @name.setter # 设置
    @name.deleter # 删除
    

多态

  • 含义
    • 一种事物的多种状态
      • 相同的功能应该有相同的名字,这样无论拿到哪个具体的名字,直接调用相同的功能即可
      • 多态在以前数据类型内置方法就接触过(len方法)

反射

  • 遇到关键字....对象....字符串就要使用反射
hasattr(): 判断对象是否含有某个字符对应的属性 
getattr(): 获取对象字符串对应的属性 
setattr(): 根据字符串给对象设置属性 
delattr(): 根据字符串给对象删除属性

反射实战

魔法方法

  • 定义
    • 其实是类中定义的双下方法。无需调用,达到某个条件就会自动触发
  • 魔法方法
    双下init      # 实例化对象时触发
    双下str       # 对象被执行打印操作触发,必须返回一个字符串,打印之后就该字符串
    双下call      # 对象加()调用触发
    双下getattr   # 对象获取不存在的属性名自动触发,返回对象获取不存在的属性名就会得到该对象
    双下setattr   # 对象操作属性值的时候自动触发>>>:对象.属性名=属性值
    双下del       # 对象在被删除(主动 被动)的时候自动触发
    双下getattribute  # 对象获取属性的时候自动触发 无论这个属性存不存在,既有__getattr__又有__getattribute__的时候,只走后面。
    双下enter     # 对象被with语法执行的时候自动触发 该方法返回什么 as关键字后面的变量名就能得到什么
    双下exit      # 对象被with语法执行并运行完with子代码之后,自动触发
    
    

  • 概念

    • 多个对象相同的数据和功能的结合体,用于记录多个对象相同的数据和功能
    面向对象编程中 类仅仅是用于节省代码,对象才是核心
    
  • 类的创建

关键字:  class
              # 类在定义阶段就会执行
模板:
class 类名:
    学生对象公共的数据 (类体的代码) 
    学生对象公共的方法 (类体的代码)
    
查看名称空间的方法:
    print(类名.__dict__)               # 使用该方法查看名称空间 可以看成是一个字典 
    print(类名.__dict__['school'])     # 使用字典的取值方式获取名字 
    print(类名.__dict__.get('choice_course')) # 使用字典的取值方式获取名字

在面向对象编程中,获取名称空间中的名字,可以采用句点符

类实例化对象:
    类名.键名 = '修改后的值' # 修改键名对应的值

经典类与新式类

    经典类:  不继承object或其子类的类(什么都不继承)
    新式类:  继承了object或其子类的类

派生方法

  • 子类里面定义的类与父类一摸一样的方法,并且进行了功能的拓展
    • 子类继承了父类的功能并且做拓展
    image.png
  • 派生方法实战

元类

  • 定义
    • 产生类的类叫元类
      • 之前使用type查看的是产生当前对象的类是谁
  • 关键字
    1.使用关键字class
    2.利用元类type
    
  • 元类中的__init__用于实例化类
  • 基本使用
    • 1.继承了type的类才可以称为元类
    class MyMetaClass(type):
        pass
    
    • 2.切换产生类的元类不能使用继承,要使用关键字metaclass声明
    class MyClass(metaclass=MyMetaClass):
        pass
    
  • 元类进阶
    • 元类可以控制类的产生过程也可以控制对象的产生过程
      • 1.对象加()执行产生该对象类里面的双下call
      • 2.类加括号执行产生该类的元类里面的双下call
    • 实例化对象所有参数都必须采用关键字的形式
    -   高度定制对象的产生过程:操作元类里面的__call__
    -   高度定制类的产生过程:操作元类里的__init__
    

双下new

  • 产生类的步骤
    • 1.产生一个空对象
    • 2.自动触发__init__方法实例化对象
    • 3.返回实例化完成的对象
  • __new__方法专门用于产生空对象(外壳)
  • __init__方法专门用于给对象添加属性(内脏)