• python摸爬滚打之day20--多继承,MRO和C3算法


    1、新式类和经典类

      在python2.2之前, 基类如果不写(), 则表示为经典类; 

      在python2.2之后, 经典类不复存在, 只存在新式类. 如果基类谁都不继承的话, 则默认继承object.

    2、MRO----()方法解释顺序

      主要用于多继承时判断属性的路径(来自于哪个类).

      经典类的MRO算法  ------树形结构的深度优先遍历

        原则: 按继承顺序从左子树到右子树, 一条道走到黑. 

     1 class A:    pass
     2 class B(A):    pass
     3 class C(A):    pass
     4 class D(B, C):    pass
     5 class E:    pass
     6 class F(D, E):    pass
     7 class G(F, D):    pass
     8 class H:    pass
     9 class Foo(H, G):    pass
    10 # MRO 顺序: H G F D B A C E
    经典类MRO顺序

    3、新式类的MRO顺序 ----> 遵循C3算法

       先由MRO确定一个线性序列, 然后查找路径由线性序列中类的顺序决定, C3算法就是生成这样的一个线性序列.

        c3算法的核心是merge算法.

        merge原则: 拿前一项的头和后面所有项的身体进行比较, 如果在后面没有出现, 则拿出这个头并划掉出现的所有该元素,前一项继续往后走;

               如果在后面项中出现, 则前一项(a)剩余全部跳过, 比较第二项(b)(用第二项(b)的头和后面所有项的身体比较, 有的话继续跳过去, 比较第三项(c)), 啥时候没有出现, 拿出并划掉后继续返回前一项(a)剩下的元素继续比较.

      注意: 可以这样查找: C3算法就是把每个环节多个类产生的共同继承留到最后去找.   

     1 class A:    pass
     2 class B(A):    pass
     3 class C(A):    pass
     4 class D(B, C):    pass
     5 class E(C, A):    pass
     6 class Y:    pass
     7 class F(D,Y, E):    pass
     8 class G(E):    pass
     9 class H(G, F):    pass
    10 
    11 # 先拆分                      再从下往上合并, 把前一项的头和后面所有项的身体进行比较, 如果后面出现了则直接跳过, 没有的话前一项接着往后走
    12 # S(H) = H + S(G) + S(F) + GF           HGFD BYEC A
    13 # S(G) = G + S(E)   GECA
    14 # S(F) = F + S(D) + S(Y) + S(E) + DYE      FDBYECA
    15 # S(E) = E + S(C) + S(A) + CA       ECA
    16 # S(D) = D + S(B) + S(C) + BC       DBCA
    17 # S(B) = B + S(A)           BA
    18 # S(C) = C + S(A)        CA
    19 print(H.mro())       # HGFD BYEC A
    新式类Mro顺序

    4、super() ----> 执行MRO中的下一个父类方法. 

     1 class Foo:
     2     def func1(self):
     3         super().func1()        # 找下一个父类  Bar
     4         print("走你2")
     5 
     6 class Bar:
     7     def func1(self):
     8         print("走你1")
     9 
    10 class Ku(Foo,Bar):
    11     def func1(self):
    12         super().func1()         # 找下一个父类 Foo
    13         print("走你3")
    14 
    15 k = Ku()
    16 k.func1()    
    17   
    18 #  MRO顺序: ku ----> Foo ----> Bar ----> object
    super()

     5、已经有继承关系了还要用super()继承呢?

       因为有时候普通的继承关系是满足不了需求的.

        比如: 用父类的方法来完成自己的一部分代码, 这个时候就能用得到super()了.

     1 class Base:
     2     def __init__(self,a,b,c):
     3         self.a = a
     4         self.b = b
     5         self.c = c
     6 
     7 class Foo(Base):
     8     def __init__(self,a,b,c,d):
     9         super(Foo, self).__init__(a,b,c)     # 用父类方法来构造自己的a,b,c, 自己再添加self.d.                                 
    10         self.d = d                           # 如果用单纯的非super继承很难实现.
    11 
    12 f = Foo(11,22,33,44)
    13 print(f.a)
    14 print(f.b)
    15 print(f.c)
    16 print(f.d)
    super()继承

        再比如: 如果继承的多个类中都存在相同的方法, 使用super能很精准地定位到要执行方法的类. 

     1 class Animal:
     2     def act(self):
     3         print("动物会动")
     4 
     5 class Cat(Animal):
     6     def act(self):
     7         print("猫会动")
     8 
     9 class BosiCat(Cat):
    10     def act(self):
    11         super(Cat, self).act()     # 可以很精准地定位到执行cat()类的下一个类的act()方法, 不用super()很难定位精确.
    12         print("波斯猫会动")
    13 
    14 b = BosiCat().act()
    super()继承
  • 相关阅读:
    【凡尘】---react-redux---【react】
    React生命周期详解
    写文章很难,ai自动生成文章为你来排忧
    怎么用ai智能写作【智媒ai伪原创】快速写文章?
    给大家介绍个Seo伪原创工具吧,可以免费用的哈
    自媒体文章难写,在线伪原创文章生成就简单了
    内容创作难吗 不妨试试智媒ai伪原创
    Ai伪原创工具,轻松几秒出爆文
    什么AI写作软件靠谱,好用?
    分享个免费伪原创工具 关键词自动生成文章
  • 原文地址:https://www.cnblogs.com/bk9527/p/9954366.html
Copyright © 2020-2023  润新知