鱼C论坛

 找回密码
 立即注册
查看: 931|回复: 2

[已解决]38讲中课后题super()语句的例子

[复制链接]
发表于 2020-4-9 23:34:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 leon_xinxin 于 2020-4-9 23:52 编辑

如图,明明B和C都是A的子类,是同一等级。为什么在输出D我感觉的时候先执行B再执行C呢?这样输出让人感觉C是B的子类。
求好的解释!

                               
登录/注册后可看大图


                               
登录/注册后可看大图
最佳答案
2020-4-10 00:06:12
本帖最后由 sunrise085 于 2020-4-10 00:07 编辑

看看这个帖子
我在这个帖子下回复了好几条,应该能帮你解惑
这是多重继承时初始化函数__init__()的内容,这个涉及到super()和__mro__的用法。
在继承的时候,子类中若需要调用父类的__init__()函数,则需要用super().__init__()。但若是多重继承,什么时候调用哪一个父类的__init__()函数,是由__mro__列表顺序给出的。

在你的这个程序中,D类的__mro__表如下:
<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>
当创建D类的实例化时,会先调用D类的__init__()函数。之后每遇到一次super().__init__()函数就会从上表 中向后找一个父类去执行它的__init__()函数,一直到列表为空或者最后一个执行的__init__()函数中没有super()__init__()函数为止。
我们现在看一下你的程序执行过程:先执行D的__init__()函数,遇到super;然后去执行B的__init__()函数,再次遇到super;接着去执行C的__init__()函数,C中没有遇到super函数,执行完毕之后返回B的__init__()函数;然后返回D的__init__()函数,结束。

假如,C中有super,而B中没有super。那么结果会更短,从D的__init__()函数进入B的__init__()函数,然后返回D的__init__()函数,结束。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-4-10 00:06:12 | 显示全部楼层    本楼为最佳答案   
本帖最后由 sunrise085 于 2020-4-10 00:07 编辑

看看这个帖子
我在这个帖子下回复了好几条,应该能帮你解惑
这是多重继承时初始化函数__init__()的内容,这个涉及到super()和__mro__的用法。
在继承的时候,子类中若需要调用父类的__init__()函数,则需要用super().__init__()。但若是多重继承,什么时候调用哪一个父类的__init__()函数,是由__mro__列表顺序给出的。

在你的这个程序中,D类的__mro__表如下:
<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>
当创建D类的实例化时,会先调用D类的__init__()函数。之后每遇到一次super().__init__()函数就会从上表 中向后找一个父类去执行它的__init__()函数,一直到列表为空或者最后一个执行的__init__()函数中没有super()__init__()函数为止。
我们现在看一下你的程序执行过程:先执行D的__init__()函数,遇到super;然后去执行B的__init__()函数,再次遇到super;接着去执行C的__init__()函数,C中没有遇到super函数,执行完毕之后返回B的__init__()函数;然后返回D的__init__()函数,结束。

假如,C中有super,而B中没有super。那么结果会更短,从D的__init__()函数进入B的__init__()函数,然后返回D的__init__()函数,结束。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-10 01:05:10 | 显示全部楼层
本帖最后由 Stubborn 于 2020-4-10 01:09 编辑

一个类的 [`__mro__`](https://docs.python.org/zh-cn/3. ... .html#class.__mro__) 属性的三个准则:

- 子类会先于父类被检查
- 多个父类会根据它们在列表中的顺序被检查
- 如果对下一个类存在两个合法的选择,选择第一个父类

这个属于第一个情况,如果没有同一个父类,那么Mro正常是先检查自身,而后从继承的父类或者兄弟类,从左到右检查,父类如果还存在继承,优先被检查。
但是B,C有同一个父类,所以,Mro的顺序是    D - B - C - A - Object
你可以尝试,去掉C的父类,看下Mro的搜索顺序。结合体验下


  1. class A: pass                                                                             
  2. class B: pass                                                                             
  3. class C(A, B): pass                                                                       
  4. print(C.mro())                                                                           
  5. # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]   
  6. class D:pass                                                                              
  7. class E(C, D):pass                                                                        
  8. print(E.mro())                                                                           
  9. # [<class '.E'>, <class '.C'>, <class '.A'>, <class '.B'>, <class '.D'>, <class 'object'>]
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-12 21:12

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表