Python 中多继承 之 MRO 详解

多继承中的 MRO 顺序:

  • 多继承指的是子类继承了多个父类

调用父类三种方法区别:

  • 父类名.父类方法(self): 在多(三级及以上)继承中, 弊端: 会出现父类被调用多次的情况( 菱形继承问题 ), 这时可用super()来解决
  • super().父类方法(): 按照 MRO 顺序查找上级父类的方法, 能保证每个父类方法只被调用一次(前提是每个类都使用super)
  • super(指定类名, self).父类方法(): 从指定类名的上级父类调用
    • super也是一个类, 在调用时内部的__new__会生成一个对象, __init__会记录父类和具体实例

引用:

  • super().__init__相对于类名.__init__,在单继承上用法基本无差
  • 但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次,具体看前面的输出结果
  • 多继承时,使用super方法,对父类的传参数,应该是由于python中super的算法导致的原因,必须把参数全部传递,在不确定参数长度的情况下, 用不定长参数代替, 否则会报错
    • *args**kwargs 为不定长参数, 其args和kwargs也是变量
      • 作为形参时: 前面加上 */** 表示该变量具有特殊功能
      • 作为参数传递时, 前面加上 */** 起到拆包作用, 会将元组传给对应函数的*args, 字典传给对应函数的**kwargs
  • 单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数,否则会报错
  • 多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍, 而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因

MRO 是什么呢?(属于广度优先算法)

  • MRO(Method Resolution Order)就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。
  • 对于你定义的每一个类,Python 会根据 C3 算法生成一个该类继承顺序表(元组)MRO,它代表了类继承的顺序, 这个顺序是由C语言中的 C3 算法决定的, 是一个保证父类只被调用一次的算法
  • print(Grandson.__mro__)     # 例如打印MRO顺序如下:

(<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)

相关知识点: 

类属性: 用来描述类的属性, 在类里方法外定义的属性称为类属性, 保存在类内存中, 在内存里是共用的

实例属性: 在__init__方法内的属性称为实例属性, 在每个对象的内存中都保存了一份, 内部会有个__class__属性指向类对象(是谁创建的?)

类对象: 类是一个特殊的对象, 类名()即类对象, 只能调用 类方法静态方法

实例对象: 由类创建的实例称为实例对象, 例如: obj = 类名(), obj

以下三种方法都保存在类的内存中:

  • 实例方法: 不需要修饰, 以 self 作为第一个参数, 无法修改类属性( 除非: obj.__class__.类属性 = xxx ),---> 对象调用
  • 类方法: @classmethod, 以 cls 作为第一个参数, 用来操作(修改/访问)类属性, --->调用(类名.类方法)
  • 静态方法: @staticmethod, 不需要传参, 普通方法(比如每个类的说明文档), 为避免放在类外与其他类的方法重复, 就封装到类里了, --->调用(类名.静态方法)
    • 注意: 类方法 和 静态方法  不推荐使用: 对象名.xxx的方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值