# 今日大纲# 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: passclass B(A): passclass C(A): passclass D(B, C): passclass E(C, A): passclass F(D, E): passclass G(E): passclass 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): # passclass Incr(Pro): def __init__(self, val): super(Incr, self).__init__(val) self.val += 1# Incr Pro Add2 Mult HaHa Initp = Incr(5)print(p.val)c = Add2(2)print(c.val) # 结果: 分析:复杂的先找出C3排序、一项项往上找# Add2# Mult# 哈哈# init# 5.0# 8.0# Add2# init# 2# 4
原文地址:https://www.cnblogs.com/z520h123/p/9960293.html
时间: 2024-11-10 02:08:24