面向对象之多重继承

一、多重继承

1、MRO概念

mro 是一个列表,列表中是根据c3算法记录的,当前class,所有可以继承的按照继承优先级排序的一个线性列表。

通过class.__mro__.可以进行查询。

c3 算法详解可以查看https://www.cnblogs.com/whatisfantasy/p/6046991.html。总结起来,其实就是将当前类,和当前类的父类的,所有的mro列表进行了一个组合,按照规则 ,将所有类的mro,按照深度查找,然后,当出现两个相同的类时,保留后一个的规则,排出,

每一个类的mro, 然后进行排序。基本的原则的就是当前类的继承顺序不能与父类的继承顺序发生冲突的原则,进行一个重新排序。这个就是一个cs的一个算法。

,进行一个排序。

 

二,关于广度优先和深度优先

2.1深度优先

深度优先的说法只有2.1以上的版本,是基于经典类,来计算当前的类的MRO

class A:

pass    这种不需要继承object的这种称之为经典类

基于上图中每一个大写字母都是一个类,用代码展现就是

class A:
    name='eric'

class B(A):
    pass

class C(A):
    name = 'ren'

class D(B ,C):
    pass

  此是,D实例化一个对象obj = D() ,这个obj 需要调用name属性,如果是深度优先,查找逻辑就是D、B、A、C、A。所以此时调用到的就是name=‘eric’ ,但是实际上,C类中的属性,已经对此属性进行了重新赋值,或者添加了新的内容,所以我们希望

看到调用的是C下面的name属性。所以此时产生的mro,这个继承顺序列表是不合理的。 这也就是所谓的深度优先

2.2

为了解决这种问题,加上python内部的改进,出现了新式类,也就是

class B(object):

    pass

这种继承object 称之为新式类,在目前的3.0版本的python中只存在新式类

基于上图进行代码实现

class A(object):
    name = 'eric'

class B(A):
    pass

class C(A):
    name ='ren'

class D(B):
    pass
class E(C):
    pass

class F(D,E):
    pass

  这个时候,在用obj = F() 实例化一个实例,在来调用name这个属性 , obj.name ,这个时候 就会根据广度优先 ,查找顺序是F、D、B、E、C、A。根据c3算法,产生一个根据这种排序的mro ,同样可以通过class.__mro__进行查看。

 

三、根据mro来判断,调用属性或者调用方法

所以当我们进行查找是的一个顺序是,优先查找当前类,然后查找继承的类,当继承多个类时,按照从左到右进行查找。当我们出现两个类继承同一个父类时,先按照广度优先,查找后,最后在查找父类。

这种查找顺序,无论是方法还是属性都是一致。

ps:例子

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

class A:
    def bar(self):
        print("BAR")
        self.f1()

class B(A):
    def f1(self):
        print("B")

class C:
    def f1(self):
        print("C")

class D(C, B):
    pass

obj = D()
obj.bar()

结果
BAR
C

  

  

 

转载于:https://www.cnblogs.com/python-ERIC/p/10395294.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值