16 继承 MRO和C3算法

一 多继承

  • Python中类与类之间可以有继承关系. 当出现了了x是一种y的的时候. 就可以使用继承关系. 即"is-a" 关系.  在继承关系中. 子类自动拥有父类中除了了私有属性外的其他所有内容.  python支持多继承. 一个类可以拥有多个父类. 
class ShenXian: # 神仙
    def fei(self):
        print("神仙都会飞")
class Monkey:   #
    def chitao(self):
        print("猴⼦喜欢吃桃子")
class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是一只猴
    pass
sxz = SunWukong()   # 孙悟空
sxz.chitao()    # 会吃桃⼦子
sxz.fei()       # 会⻜
#悟空既是猴子也是神仙所以可以多继承,也就可以执行两个类中的方法
View Code

         但是如果父类有重名的方法,又该先访问谁馁?这时就涉及到如何查找父类方法的这么一个问题。即MRO(method resolution order) 问题。在python中这是一个很复杂的问题。因为在不同的 python版本中使用的是不同的算法来完成MRO的。 

  python2.3以前的解决方法:是深度优先遍历方案,什么是深度优先,就是一条路走到头,然后再回来,继续找下一个。 

  二、 目前python采用的是新式的MRoOo的算法,C3算法:

class A:
    pass
class B(A):
    pass
class C(A):
    pass
class D(B, C):
    pass
class E(C, A):
    pass
class F(D, E):
    pass
class G(E):
    pass
class H(G, F):
    pass

                                 步骤                    结果
L(H) = H + L(G) + L(F) + GF      H GECA  FDBECA GF       HGFDBECA
L(G) = G + L(E) + E              G ECA E                 GECA
L(F) = F + L(D) + L(E) + DE      F DBCA ECA DE           FDBECA
L(E) = E + L(C) + L(A) + CA      E CA A CA               ECA
L(D) = D + L(B) + L(C) + BC      D BA CA BC              DBCA
L(B) = B + L(A) + A              B A A                   BA
L(C) = C + L(A) + A              C A A                   CA
L(A) = A                         A                       A

print(H.mro())
# [<class '__main__.H'>, <class '__main__.G'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>,
# <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

      具体算法使用最后一步说明  L(H) = H  GECA  FDBECA  GF 一共四项对于每一项后面都要加上继承的组合 GF,E,DE,CA等 ,从第一项  H 开始,和后面每一项除了他们的第一个字母比较如果后面项的‘身体’没有出现H  则拿出来,  如果出现相同的 H 就先跳过第一项,拿出第二项第一个继续和后面项的身体比较以此类推。根据这个例子:

       1 首先 H 后面项身体没出现所以提取H.

       2.G和后面项比较后面项身体也没有出现提取G(此刻删除所有以G开头项的G).

       3.剩下 ECA  FDBECA  F  继续比较E发现第二项身体有跳过第一项,使用第二项开头的 F 和后面比较后面也没有 提取 F(记得删除 剩下的项 ECA DBECA) 此时提取出的有(HGF).

      4.回到第一项使用E比较 发现还是有 继续跳过 使用第二项 D比较后面 提取D.

      5 返回第一项继续拿到E 第二项依然有 依然拿到 B.

      6.返回到第一项E比较此时第二项身体没有E了 提取第一项E并删除E 此刻剩下 CA  CA 提取了 HGFDBE  所以后面两项为CA.

 三  supper()

class ShengWu:
    def dong(self): # 实例方法
        print(self)
        print("我是生物")

class Animal(ShengWu):
   def dong(self):
       print('我是动物')

class Cat(Animal):
    def dong(self): # 子类中出现了和父类重名的内容. 表示对父类的方法的覆盖(重写). 半盖(java)
        super().dong()  #找到Animal
        super(Animal, self).dong() # 可以定位到Animal. 找Animal的下一个即生物
        # super(类, 对象).方法()  找到MRO中的类. 找这个类的下一个. 去执行方法
        print("我的猫也会动")
View Code
原文地址:https://www.cnblogs.com/-0121/p/9955066.html