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
结合场景再看三个关注点
- 重写替换子类入口,但仍可
super复用基类。 - 审计逻辑集中,避免每个通道复制。
- 多继承时
super语义见 MRO 篇,不要脑补“只调字面父类”。
核心概念与准确模型
class Child(Parent):- 属性查找走 MRO
super()在类方法/实例方法中绑定当前类与实例/类isinstance/issubclass做运行时判断
边界情况与反直觉行为
- 忘记 super 初始化导致基类字段缺失。
- 菱形继承必须理解 MRO。
- 私有名改写
__x变成_Cls__x,继承时需注意。
常见误区
[!warning] 常见误区:super 就是 Parent.method(self) 错误理解:永远调用写法上的父类。
正确模型:按 MRO 找下一个;协作式多继承依赖这一点。
工程实践
- 优先浅继承 + 组合。
- 模板方法:基类定流程,子类填钩子。
- 公共初始化用
super().__init__链。
本节总结
继承解决差异化扩展;super 是协作调用协议。深树继承往往是设计味道。
自测题
- 子类重写后如何复用父逻辑?
- 为什么说 super 与 MRO 相关?
参考答案
- 在重写方法内
super().method(...)。 - super 查找的是 MRO 中的下一类型,不是语法上的直接父类写死。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| super() | 文档 | super |
| Tutorial – Inheritance | 教程 | 继承 |