Python 多重继承与 MRO

多重继承用 C3 线性化得到 MRO;super 沿 MRO 协作,混入(mixin)应保持正交。

#type / concept #status / growing #tech / dev #resource / python #tech / lang / python

[!info] 关联笔记

Python 多重继承与 MRO

这个概念为什么出现

日志混入、权限混入、序列化混入……多重继承能拼能力,但若查找顺序不明,会出现“调到了意料外的实现”。Python 用 C3 线性化生成 MRO(Method Resolution Order)。

[!abstract] 一句话理解 多基类时属性查找按 Cls.__mro__ 顺序;super() 走向 MRO 中的下一个类,使混入可协作。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:API Handler 混入鉴权与审计

# mro_mixin_demo.py
# 业务意图:AuthMixin + AuditMixin 叠在 Handler 上。
# 教学点:
# - __mro__ 顺序;
# - super 协作链;
# - mixin 应调用 super。

class Handler:
    def handle(self, req: str) -> str:
        return f"handle:{req}"


class AuditMixin:
    def handle(self, req: str) -> str:
        return "audit|" + super().handle(req)


class AuthMixin:
    def handle(self, req: str) -> str:
        if not req.startswith("ok:"):
            return "deny"
        return "auth|" + super().handle(req)


class ApiHandler(AuthMixin, AuditMixin, Handler):
    pass


def main() -> None:
    print(ApiHandler.__mro__)
    print(ApiHandler().handle("ok:pay"))
    print(ApiHandler().handle("bad"))


if __name__ == "__main__":
    main()

建议运行:

python mro_mixin_demo.py

期望输出(MRO 元组含类对象 repr):

(<class '__main__.ApiHandler'>, <class '__main__.AuthMixin'>, <class '__main__.AuditMixin'>, <class '__main__.Handler'>, <class 'object'>)
auth|audit|handle:ok:pay
deny

结合场景再看三个关注点

  1. 基类书写顺序影响 MRO:AuthMixinAuditMixin 前。
  2. mixin 必须 super,否则链条断开。
  3. 鉴权失败直接返回,不再进入后续 handle。

核心概念与准确模型

  • 查看:Class.__mro__Class.mro()
  • C3:既保持局部优先级又保持单调性
  • 无法线性化时类创建失败

边界情况与反直觉行为

  1. 父类顺序冲突导致 TypeError: Cannot create a consistent method resolution order
  2. 钻石继承靠 MRO 保证每个类最多出现一次协作路径
  3. mixin 带状态易变乱——优先无状态 mixin

常见误区

[!warning] 常见误区:多重继承是默认设计 错误理解:能力多就多继承。
正确模型:组合、协议、装饰器往往更清晰;mixin 要正交且文档化 MRO 预期。

工程实践

  • 命名 XxxMixin
  • 只混入行为,不混入复杂构造参数
  • 单测打印 __mro__ 锁定顺序

本节总结

MRO 是多重继承的地图;super 是沿地图前进的方式。先会读 __mro__,再写 mixin。

自测题

  1. 如何查看查找顺序?
  2. mixin 为什么要调用 super?
参考答案
  1. Cls.__mro__
  2. 把控制权交给 MRO 下一类型,形成协作链。

延伸阅读与资料来源

资料类型支撑内容
C3 method resolution历史文档C3 说明
Data model – MRO规范类型对象
创建于 2026/5/20 更新于 2026/7/15