看了网上许多关于super、mro、C3的介绍感觉没有一份很容易初学者理解的文档,直接看C3算法的话,比较难理解,也没必要,如果掌握一套规律的话,会轻松许多。我将网上这些博主的文章进行一个梳理总结,最后形成一套实用的关于super、mro、C3的理解介绍。
1、super
super()是一种将子类与父类联系起来的一种方法,子类通过继承父类,可以使用父类的方法和属性,也可以自己定义属于自己的方法和属性。super方法主要用在多继承中,在单继承时直接调用父类方法即可
下面这个是SGD源码的一部分,根据这份源码,
class SGD(Optimizer): def __init__(self, params, lr=required, momentum=0, dampening=0, weight_decay=0, nesterov=False): defaults = dict(lr=lr, momentum=momentum, dampening=dampening, weight_decay=weight_decay, nesterov=nesterov) if nesterov and (momentum <= 0 or dampening != 0): raise ValueError("Nesterov momentum requires a momentum and zero dampening") super(SGD, self).__init__(params, defaults) def __setstate__(self, state): super(SGD, self).__setstate__(state) for group in self.param_groups: group.setdefault('nesterov', False)
这是SGD类中的代码
有2点需要补充说明:
1、super联系父类的时候,需要调用父类的方法,包括所带的形参写完整,子类不够的形参需要额外加上
2、super联系父类的时候,不只是可以调用__init__,而且还可以调用父类其他的方法
3、python3可以写成super().__init__()这种写法了。
4、类都默认继承object类
另外,在super的使用过程中,还需要注意初始化对继承的影响:
1、子类继承父类,但不执行__init__方法,那么会自动继承父类属性。
2、子类继承父类,执行了__init__方法,且不调用super初始化父类构造函数,那么子类不会自动继承父类属性。
3、子类继承父类,执行了__init__方法,且调用了super初始化了父类的构造函数,那么子类会继承父类属性。
2、mro
Python的MRO,方法解析顺序,即在调用方法时,会对当前类以及所有的基类进行一个搜索,以确定该方法之所在,而这个搜索的顺序就是MRO。然后python会按照这个顺序去执行类之间的调用问题。
直接上例子
class A1(): def __init__(self): print('A1') super().__init__() class A2(): def __init__(self): print('A2') super().__init__() class A3(): def __init__(self): print('A3') super().__init__() class B1(A1, A2): def __init__(self): print('B1') super().__init__() class B2(A2): def __init__(self): print('B2') super().__init__() class B3(A2, A3): def __init__(self): print('B3') super().__init__() class C1(B1): def __init__(self): print('C1') super().__init__() class C2(B1, B2): def __init__(self): print('C2') super().__init__() class C3(B2, B3): def __init__(self): print('C3') super().__init__() class D(C1, C2, C3): def __init__(self): print('D') super().__init__() d = D() print(D.__mro__)
输出如下:
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.B1'>, <class '__main__.A1'>, <class '__main__.C3'>, <class '__main__.B2'>, <class '__main__.B3'>, <class '__main__.A2'>, <class '__main__.A3'>, <class 'object'>)
那么这个程序是按怎么个顺序依次去执行那些方法呢,就是按照MRO中的顺序。
那么这个顺序如何自己手写出来呢?这就是C3算法,用于计算出MRO,得出执行顺序
3、c3算法
但是我在这里想告诉大家如何根据C3算法找出规律,从而自己写出顺序
还是上手例子,根据上面这个图,我们可以列出下面这个表,这个表示网上一个博主做的,可以说做出这张表就是做出了答案,那这张表“实际取出的类”怎么推出来的呢?我拿过来提炼出一些比较直接的规律
规律1:预查找父类按左边优先原则,比如第一行,当前类D的预查找父类选最左边的C1,而不是C2、C3。
规律2:当“预查找父类是否还有其他子类?同时又是最底层查找类的父类或父父类、父父父...类”没有的时候,直接选取预查找父类作为答案。当这项有类的时候,若“最底层的未查找父类”还有,则优先选它,若没有了,则选取这项类作为答案。
规律3:当预查找父类是object,只要最底层的未查找父类还有,就选这个最底层的未查找父类。若没有,则“预查找父类是否还有其他子类?同时又是最底层查找类的父类或父父类、父父父...类”有类的时候,就选这个类,没有的话,答案就是object
另外,
如何去画图:
1、子类永远画在父类的下面,并用有向箭头指向父类
2、遇到多继承则按代码中继承列表的顺序从左往右写。如果有多个子类继承了同一个父类,那么这个父类则放在它能够出现的所有位置中最左的位置。需遵循图里面的广度优先原则进行遍历(在广度优先原则的前提下又优先遍历左边的):
练习:
下面这个是网上的一份代码,看懂上面的规律以及如何画有向图之后,就可以顺利得出MRO的值了
class A: def __init__(self): print('A') class B(A): def __init__(self): print('B') super().__init__() class C(A): def __init__(self): print('C') super().__init__() class D(A): def __init__(self): print('D') super().__init__() class E(B, C): def __init__(self): print('E') super().__init__() class F(C, D): def __init__(self): print('F') super().__init__() class G(E, F): def __init__(self): print('G') super().__init__()
首先,画图
然后列表
当前类最底层未查找的父类预查找的父类预查找父类是否为object预查找父类是否有其他子类,同时又是最底层查找类的父类、父父类实际取出的类GE、FEnonoEEFBnonoBBFAno有,CFFnoCnonoCCnoAno有,DDDnoAnonoAAnoobjectyesnoobject
答案:
mro:GEBFC
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 《暗喻幻想》顺风耳作用介绍
- 崔健1985-梦中的倾诉[再版][WAV+CUE]
- 黄子馨《追星Xin的恋人们2》HQ头版限量编号[WAV+CUE]
- 孟庭苇《情人的眼泪》开盘母带[低速原抓WAV+CUE]
- 孙露《谁为我停留HQCD》[低速原抓WAV+CUE][1.1G]
- 孙悦《时光音乐会》纯银CD[低速原抓WAV+CUE][1.1G]
- 任然《渐晚》[FLAC/分轨][72.32MB]
- 英雄联盟新英雄安蓓萨上线了吗 新英雄安蓓萨技能介绍
- 魔兽世界奥杜尔竞速赛什么时候开启 奥杜尔竞速赛开启时间介绍
- 无畏契约CGRS准星代码多少 CGRS准星代码分享一览
- 张靓颖.2012-倾听【少城时代】【WAV+CUE】
- 游鸿明.1999-五月的雪【大宇国际】【WAV+CUE】
- 曹方.2005-遇见我【钛友文化】【WAV+CUE】
- Unity6引擎上线:稳定性提升、CPU性能最高提升4倍
- 人皇Sky今日举行婚礼!电竞传奇步入新篇章