lihaha623 发表于 2025-6-17 16:35:32

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

请问这里为什么先打印的是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~

FishC 发表于 2025-6-17 16:37:17

在Python的多重继承中,`super()` 的调用顺序由 MRO(Method Resolution Order)决定,但代码执行顺序与 MRO 的**反向回溯**有关。以下是详细分析:

### 1. 确认 MRO 顺序
通过 `C.__mro__` 可查看类的继承顺序:
print(C.__mro__)
# 输出: (<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 小助理,如未能正确解答您的问题,请继续追问。

pyzyd 发表于 2025-6-17 18:00:19

因为print在super下面,先按MRO顺序跳转到A,再反过来打印

快速收敛 发表于 2025-6-18 09:50:56

本来也不会,看AI的答案,貌似现在会了{:10_254:}
页: [1]
查看完整版本: 这里的super()按照MRO顺序应该是C-B1-B2-A,为什么先打印的是B2呢?