• 第二十天- 多继承 经典MRO 新式MRO super()


    # 多继承:
    # 在继承关系中.⼦类自动拥有⽗类中除私有属性外其他所有内容.python⽀持多继承.子类可拥有多⽗类.
     1 class ShenXian: # 神仙
     2 
     3  def fei(self):
     4     print("神仙都会⻜")
     5 
     6 class Monkey: #
     7 
     8  def chitao(self):
     9     print("猴⼦喜欢吃桃⼦")
    10 
    11 class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是⼀只猴(自己有先自己,然后靠最近的,再其他)
    12     pass
    13 
    14 # sxz = SunWukong() # 孙悟空
    15 # sxz.chitao() # 会吃桃⼦
    16 # sxz.fei() # 会⻜
    17 
    18 # 这就是多继承,但当两个⽗类中出现了重名⽅法的时候.就涉及到如何查找⽗类⽅法的问题.
    19 # 即下面的 MRO(method resolution order) 问题
    # 经典类MRO算法:
    # 在python2.2之前用,现已弃用(做面试题参考) 采用的树形结构的深度递归遍历
    # 方法:从头开始.从左往右,一条道跑到底,然后回头.继续⼀条路跑到头.(画图)
     1 # 画图排顺序 现用python版本已无法验证
     2 class A:
     3  pass
     4 class B(A):
     5  pass
     6 class C(A):
     7  pass
     8 class D(B, C):
     9  pass
    10 class E:
    11  pass
    12 class F(D, E):
    13  pass
    14 class G(F, D):
    15  pass
    16 class H:
    17  pass
    18 class Foo(H, G):
    19  pass
    20 
    21 #  结果 : FOO--H--G--F--D--B--A--C--E
    View Code

    # 新式类MRO算法(C3):
    # 先拆后合 从下向上合并,拿出每一项的头和后一项的身体进行比较.
    # 如果出现了就过,从后一项的头继续去比较.如果不出现就出来放到结果。
    # (注意:每次都是拿 头一项 的头和后面的身体比较,出现了就过,这时把后一项的头作为头一项继续去比较,
    # 若后一项的头在后面身体还有,继续这个操作...直到后面身体没有再返回前面的头,理解成一个循环)
     1 class A:
     2     pass
     3 class B(A):
     4     pass
     5 class C(A):
     6     pass
     7 class D(B, C):
     8     pass
     9 class E(C, A):
    10     pass
    11 class F(D, E):
    12     pass
    13 class M(F, E):
    14     pass
    15 class N:
    16     pass
    17 class P(M,N):
    18     pass
    19 class G(P):
    20     pass
    21 class O:
    22     pass
    23 class X(O):
    24     pass
    25 class H(G, X, F):
    26     pass
    27 print(H.__mro__)
    28 
    29 
    30 '''
    31 # 拆 注意别漏了末尾的 “GXF”
    32 # 当类里面只有单个继承时不需要 
    33 L(H) = H + L(G) + L(X) + L(F) + GXF     HGPMXFDBECANO
    34 
    35 L(G) = G + L(P)               GPMFDBECAN
    36 L(X) = X + L(O)               XO
    37 L(F) = F + L(D) + L(E) + DE   FDBECA
    38 
    39 L(P) = P + L(M) + L(N) + MN   PMFDBECAN
    40 L(O) = O
    41 L(D) = D + L(B) + L(C) + BC    DBCA
    42 L(E) = E + L(C) + L(A) + CA    ECA
    43 
    44 L(M) = M + L(F) + L(E) + FE    MFDBECA
    45 
    46 L(N) = N         
    47 L(B) = B + L(A)  BA
    48 L(C) = C + L(A)  CA
    49 L(A) = A         
    50 
    51 
    52 #  HGPMXFDBECANO
    View Code
    # super():
    # super是查找mro顺序中的下一个
    # 单继承中我们可以认为super是对父类中的属性或方法的引入
    # super()常用地方:
    # 1.访问⽗类的构造⽅法
    # 2.⼦类⽅法调⽤⽗类(MRO)中的⽅法
     1 # 访问⽗类的构造⽅法
     2 class Foo1:
     3  def __init__(self, a, b, c):
     4     self.a = a
     5     self.b = b
     6     self.c = c
     7 class Bar(Foo1):
     8     def __init__(self, a, b, c, d):
     9         super().__init__(a, b, c) # 访问⽗类的构造⽅法 对父类中的属性引入
    10         self.d = d
    11 
    12 b = Bar(1, 2, 3, 4)
    13 print(b.__dict__)  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
     1 # 当⼦类⽅法想调⽤⽗类(MRO)⽅法
     2 class ShengWu:
     3     def dong(self): # 实例方法
     4         print(self)
     5         print("我是生物")
     6 
     7 class Animal(ShengWu):
     8    pass
     9 
    10 class Cat(Animal):
    11     def dong(self): # 子类中出现了和父类重名的内容. 表示对父类的方法的覆盖(重写).
    12         super(Animal, self).dong() # 定位到Animal. 找Animal的下一个
    13         # super(类, 对象).方法()  找MRO中的类. 找这个类的下一个. 去执行方法
    14         print("我的猫也会动")
    15 
    16 # self 依然是谁调用就是谁
    17 # 找MRO中的下一个
    18 # Cat -> Animal -> ShengWu ->Object
    19 
    20 c = Cat()
    21 print(c)
    22 c.dong()
    View Code
    
    
    # 总结 不管super()写在哪⼉.在哪⼉执⾏.⼀定先找MRO列表.根据MRO列表的顺序往下找.否则⼀切都是错的
  • 相关阅读:
    vue入门:(方法、侦听器、计算属性)
    vue入门:(模板语法与指令)
    前端资源
    CSS3总结七:变换(transform)
    CSS总结六:动画(一)ransition:过渡、animation:动画、贝塞尔曲线、step值的应用
    设计模式(一):简单工厂
    正则命令积累
    命令模式 & 策略模式 & 模板方法
    抽象工厂:简单游戏角色
    简单工厂模式—>工厂模式
  • 原文地址:https://www.cnblogs.com/xi1419/p/9955681.html
Copyright © 2020-2023  润新知