python D20 多继承C3算法super()
Posted 我是一名劍客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python D20 多继承C3算法super()相关的知识,希望对你有一定的参考价值。
# 今日大纲
# 1、多继承
# 继承:x是一种y的时候,可以使用继承关系."is a"
# 一个类同时继承多个类(python, c++)
# eg:孙悟空是猴子,还是神仙,还是妖怪
# 2、经典类的MRO
# 通过树形结构的深度优先遍历
# 一条道走到黑(从左往右)
# 3、新式类的MRO(重点、面试题)c3算法
# 先拆分
# 在合并,第一项的头和后面所有项的身子(除了头以外的部分)进行比较,如果都没有就拿出来,如果出现了,就跳过到后一项,后一项查一个完在跳会原来的位置继续上述动作
# 4、super() (重点)
# 找MRO(新式的)的顺序的下一个
# 一、pytohn多继承
# python支持多继承,一个类可以拥有多个父类
# class ShenXian: # 神仙
# def fei(self):
# print("神仙都会?")
# class Monkey: # 猴
# def chitao(self):
# print("猴?喜欢吃桃?")
# class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是?只猴
# pass
# sxz = SunWukong() # 孙悟
# sxz.chitao() # 会吃桃?
# sxz.fei() # 会?
# 多继承存在一个问题,当出现两个父类中出现虫棉方法的时候,该怎么办
# 这就涉及到如何查找父类方法的这么一个问题,即MRO(method resolution order)
# 问题,在python中这是一个复杂的问题,因为在不同的python版本中使用的是不同的算法来
# 完成MRO的,首先我们能见到的有两个版本python2/python3
# python2
# 一个交经典类,在python2.2之前,一直使用的是经典类,经典类的在
# 基类的跟如果什么都不写,表示继承xxx
# 一个叫新式类,在python2.2之后出现了新式类,新式类的特点是
# 基类的跟是object
# python3
# python3中使用的都是新式类,如果基类谁都不继承,拿这个类会默认继承object
# 二、经典类的MRO
# 经典类的MRO:通过树形结构的深度优先遍历 一条道走到黑(从左往右)
# 三、新式类的MRO
# python中的新式类的MRO是采用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
# 首先我们确定从H开始找,也就是说创建的是H的对象
# 如果重H找,那找到H+H的父类C3,我们设C3算法是L(x)
# 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) =(DBCA)
# L(B) = B + L(A) + A = (BA)
# L(C) = C +L(A) +A = (CA)
# H.__mro__可以查看H的C3算法的排列
# 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‘>)
# 四、super() 超类
# super()可以帮我们执行MRO中下一个父类的方法,通常super()有两个使用的地方:
# 1、可以访问父类构造方法
# 2、当子类方法想调用父类(MRO)中的方法
# 第一种
# class Foo:
# def __init__(self, a, b, c):
# self.a = a
# self.b = b
# self.c = c
#
# class Bar(Foo):
# def __init__(self, a, b, c, d):
# super().__init__(a, b, c) # 访问?类的构造?法
# self.d = d
# b = Bar(1, 2, 3, 4)
# print(b.__dict__)
# 结果 {‘a‘: 1, ‘b‘: 2, ‘c‘: 3, ‘d‘: 4}
# 这样就方便子类,不需要写那么多,直接用父类的构造帮我们完成一部分代码
# 第二种
# class Foo:
# def func1(self):
# super().func1() # 此时找的是MRO顺序中下?个类的func1()?法
# print("我的?家. 就住在这个屯")
# class Bar:
# def func1(self):
# print("你的?家. 不在这个屯")
#
# class Ku(Foo, Bar):
# def func1(self):
# super().func1() # 此时super找的是Foo
# print("他的?家. 不知道在哪个屯")
# k = Ku() # 先看MRO . KU, FOO, BAR object
# k.func1()
# k2 = Foo() # 此时的MRO. Foo object
# k2.func1() # 报错 # Foo这个类没有继承 直接报错
# 面试题
# MRO + super ?试题
class Init(object):
def __init__(self, v):
print("init")
self.val = v
class Add2(Init):
def __init__(self, val):
print("Add2")
super(Add2, self).__init__(val)
print(self.val)
self.val += 2
class Mult(Init):
def __init__(self, val):
print("Mult")
super(Mult, self).__init__(val)
self.val *= 5
class HaHa(Init):
def __init__(self, val):
print("哈哈")
super(HaHa, self).__init__(val)
self.val /= 5
class Pro(Add2,Mult,HaHa): #
pass
class Incr(Pro):
def __init__(self, val):
super(Incr, self).__init__(val)
self.val += 1
# Incr Pro Add2 Mult HaHa Init
p = Incr(5)
print(p.val)
c = Add2(2)
print(c.val)
# 结果: 分析:复杂的先找出C3排序、一项项往上找
# Add2
# Mult
# 哈哈
# init
# 5.0
# 8.0
# Add2
# init
# 2
# 4
以上是关于python D20 多继承C3算法super()的主要内容,如果未能解决你的问题,请参考以下文章
Python基础13_类与类型, MRO, C3算法, super()
转 -- Python: 多继承模式下 MRO(Method Resolution Order) 的计算方式关乎super