Python 继承、重写与 super

继承复用与重写行为;super 按 MRO 协作调用,而不是“字面父类硬链接”。

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

[!info] 关联笔记

Python 继承、重写与 super

这个概念为什么出现

支付渠道、通知发送器常有“通用流程 + 差异步骤”。继承让子类重写差异;super() 让扩展点与父类实现协作,而不是复制粘贴。

[!abstract] 一句话理解 子类继承父类属性查找;重写覆盖同名方法;super() 按 MRO 找到下一类型并协作调用。

最小可运行示例

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

场景:通知发送基类记录审计,邮件通道补充主题

# notify_super_demo.py
# 业务意图:基类统一审计,子类扩展发送细节。
# 教学点:
# - 继承与重写;
# - super() 调用父实现;
# - 子类扩展而非复制。

class Notifier:
    def send(self, user_id: str, message: str) -> str:
        # 业务:所有通道先记审计。
        audit = f"audit:{user_id}"
        return f"{audit}|sent:{message}"


class EmailNotifier(Notifier):
    def send(self, user_id: str, message: str) -> str:
        base = super().send(user_id, message)
        return f"{base}|channel=email|subject=notice"


def main() -> None:
    print(EmailNotifier().send("u1", "hello"))


if __name__ == "__main__":
    main()

建议运行:

python notify_super_demo.py

期望输出:

audit:u1|sent:hello|channel=email|subject=notice

结合场景再看三个关注点

  1. 重写替换子类入口,但仍可 super 复用基类。
  2. 审计逻辑集中,避免每个通道复制。
  3. 多继承时 super 语义见 MRO 篇,不要脑补“只调字面父类”。

核心概念与准确模型

  • class Child(Parent):
  • 属性查找走 MRO
  • super() 在类方法/实例方法中绑定当前类与实例/类
  • isinstance / issubclass 做运行时判断

边界情况与反直觉行为

  1. 忘记 super 初始化导致基类字段缺失。
  2. 菱形继承必须理解 MRO。
  3. 私有名改写 __x 变成 _Cls__x,继承时需注意。

常见误区

[!warning] 常见误区:super 就是 Parent.method(self) 错误理解:永远调用写法上的父类。
正确模型:按 MRO 找下一个;协作式多继承依赖这一点。

工程实践

  • 优先浅继承 + 组合。
  • 模板方法:基类定流程,子类填钩子。
  • 公共初始化用 super().__init__ 链。

本节总结

继承解决差异化扩展;super 是协作调用协议。深树继承往往是设计味道。

自测题

  1. 子类重写后如何复用父逻辑?
  2. 为什么说 super 与 MRO 相关?
参考答案
  1. 在重写方法内 super().method(...)
  2. super 查找的是 MRO 中的下一类型,不是语法上的直接父类写死。

延伸阅读与资料来源

资料类型支撑内容
super()文档super
Tutorial – Inheritance教程继承
创建于 2026/5/20 更新于 2026/7/15