鱼C论坛

 找回密码
 立即注册
查看: 71|回复: 3

[已解决]这里的super()按照MRO顺序应该是C-B1-B2-A,为什么先打印的是B2呢?

[复制链接]
发表于 前天 16:35 | 显示全部楼层 |阅读模式

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

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

x
请问这里为什么先打印的是B2?
>>> class A:
...     def __init__(self):
...         print("哈喽,我是A~")
...
>>> class B1(A):
...     def __init__(self):
...        super().__init__()
...        print("哈喽,我是B1~")
...               
>>> class B2(A):
...     def __init__(self):
...         super().__init__()
...         print("哈喽,我是B2~")
...
>>> class C(B1, B2):
...     def __init__(self):
...         super().__init__()
...         print("哈喽,我是C~")
...
>>> c = C()
哈喽,我是A~
哈喽,我是B2~
哈喽,我是B1~
哈喽,我是C~
最佳答案
前天 16:37
在Python的多重继承中,`super()` 的调用顺序由 MRO(Method Resolution Order)决定,但代码执行顺序与 MRO 的**反向回溯**有关。以下是详细分析:

### 1. 确认 MRO 顺序
通过 `C.__mro__` 可查看类的继承顺序:
  1. print(C.__mro__)
  2. # 输出: (<class '__main__.C'>, <class '__main__.B1'>, <class '__main__.B2'>, <class '__main__.A'>, <class 'object'>)
复制代码

顺序为:**C → B1 → B2 → A**

### 2. `super()` 的执行逻辑
- **`super()` 本质**:不是直接调用父类,而是按 MRO 顺序调用**下一个类**。
- **代码执行特点**:每个类的 `__init__` 中,`super().__init__()` 会先跳转到下一个类,待下一个类全部执行完毕后,才继续执行当前类剩余的代码。

### 3. 逐步解析 `c = C()` 的执行流程
| 步骤 | 当前执行位置          | 动作                         | 输出结果              |
|------|-----------------------|------------------------------|-----------------------|
| 1    | `C.__init__`          | 调用 `super().__init__()` → 跳转到 `B1.__init__` | 无输出 |
| 2    | `B1.__init__`         | 调用 `super().__init__()` → 跳转到 `B2.__init__` | 无输出 |
| 3    | `B2.__init__`         | 调用 `super().__init__()` → 跳转到 `A.__init__` | 无输出 |
| 4    | `A.__init__`          | 执行 `print("哈喽,我是A~")` | `哈喽,我是A~`       |
| 5    | 返回 `B2.__init__`    | 执行 `print("哈喽,我是B2~")` | `哈喽,我是B2~`     |
| 6    | 返回 `B1.__init__`    | 执行 `print("哈喽,我是B1~")` | `哈喽,我是B1~`     |
| 7    | 返回 `C.__init__`     | 执行 `print("哈喽,我是C~")` | `哈喽,我是C~`       |

### 4. 关键结论
- **先打印 `B2` 的原因**:  
  当执行到 `B2.__init__` 时,`super().__init__()` 会先完成整个 `A.__init__` 的调用,然后才返回到 `B2` 执行后续代码(即打印 `B2`)。
- **核心规律**:  
  MRO 决定跳转顺序(C→B1→B2→A),但实际打印顺序是**从最底层类(A)开始反向回溯**执行剩余代码,因此输出顺序为:  
  `A → B2 → B1 → C`

### 简单记忆口诀
MRO 正序跳转,代码逆序执行  
(跳转按 C→B1→B2→A,打印按 A→B2→B1→C)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 前天 16:37 | 显示全部楼层    本楼为最佳答案   
在Python的多重继承中,`super()` 的调用顺序由 MRO(Method Resolution Order)决定,但代码执行顺序与 MRO 的**反向回溯**有关。以下是详细分析:

### 1. 确认 MRO 顺序
通过 `C.__mro__` 可查看类的继承顺序:
  1. print(C.__mro__)
  2. # 输出: (<class '__main__.C'>, <class '__main__.B1'>, <class '__main__.B2'>, <class '__main__.A'>, <class 'object'>)
复制代码

顺序为:**C → B1 → B2 → A**

### 2. `super()` 的执行逻辑
- **`super()` 本质**:不是直接调用父类,而是按 MRO 顺序调用**下一个类**。
- **代码执行特点**:每个类的 `__init__` 中,`super().__init__()` 会先跳转到下一个类,待下一个类全部执行完毕后,才继续执行当前类剩余的代码。

### 3. 逐步解析 `c = C()` 的执行流程
| 步骤 | 当前执行位置          | 动作                         | 输出结果              |
|------|-----------------------|------------------------------|-----------------------|
| 1    | `C.__init__`          | 调用 `super().__init__()` → 跳转到 `B1.__init__` | 无输出 |
| 2    | `B1.__init__`         | 调用 `super().__init__()` → 跳转到 `B2.__init__` | 无输出 |
| 3    | `B2.__init__`         | 调用 `super().__init__()` → 跳转到 `A.__init__` | 无输出 |
| 4    | `A.__init__`          | 执行 `print("哈喽,我是A~")` | `哈喽,我是A~`       |
| 5    | 返回 `B2.__init__`    | 执行 `print("哈喽,我是B2~")` | `哈喽,我是B2~`     |
| 6    | 返回 `B1.__init__`    | 执行 `print("哈喽,我是B1~")` | `哈喽,我是B1~`     |
| 7    | 返回 `C.__init__`     | 执行 `print("哈喽,我是C~")` | `哈喽,我是C~`       |

### 4. 关键结论
- **先打印 `B2` 的原因**:  
  当执行到 `B2.__init__` 时,`super().__init__()` 会先完成整个 `A.__init__` 的调用,然后才返回到 `B2` 执行后续代码(即打印 `B2`)。
- **核心规律**:  
  MRO 决定跳转顺序(C→B1→B2→A),但实际打印顺序是**从最底层类(A)开始反向回溯**执行剩余代码,因此输出顺序为:  
  `A → B2 → B1 → C`

### 简单记忆口诀
MRO 正序跳转,代码逆序执行  
(跳转按 C→B1→B2→A,打印按 A→B2→B1→C)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 前天 18:00 | 显示全部楼层
因为print在super下面,先按MRO顺序跳转到A,再反过来打印
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 09:50 | 显示全部楼层
本来也不会,看AI的答案,貌似现在会了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-19 19:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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