super() 是 python 多重继承中确保 mro 正确执行的必需机制,所有参与类必须统一使用,否则链式调用会静默中断;其三种写法各适配不同上下文,而显式父类调用仅适用于绕过 mro 的特定场景。

super() 是 Python 中调用父类方法的推荐方式,尤其在多重继承场景下,它能避免重复调用、保证方法解析顺序(MRO)正确。直接用 ParentClass.method(self) 看似简单,但容易在菱形继承中出错——比如 Base.__init__() 被执行两次。
为什么 super() 在多重继承里不能省略
当类结构是 C(A, B) 且 A 和 B 都继承自 Base 时,手动写 A.__init__(self) 和 B.__init__(self) 会导致 Base.__init__() 运行两次。而 super().__init__() 会按 MRO 链自动跳转到下一个类,只调一次 Base。
- MRO 可通过
C.__mro__查看,例如(C, A, B, Base, object) -
super()在A.__init__()里不是“调 A 的父类”,而是“调 MRO 中 A 后面那个类的__init__” - 所有参与继承链的类都必须使用
super(),否则链会中断
super() 的三种写法及适用场景
super() 有三种调用形式,行为不同:
-
super():仅限类内部方法中使用,隐式绑定当前类和self,最常用 -
super(cls, obj):显式指定类和实例,用于在非绑定上下文(如静态方法、类方法)中触发父类逻辑 -
super(cls, type):用于类方法中,第二个参数传入类本身(而非实例),例如super(cls, cls).classmethod_name()
错误示例:super(Child, self).__init__() 在 Python 3 中完全等价于 super().__init__(),但冗余且易写错参数顺序;不推荐在普通实例方法中显式传参。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
不调用 super() 的常见后果
子类覆盖了 __init__ 却没调父类初始化,会导致父类字段缺失或逻辑未触发:
-
AttributeError: 'Child' object has no attribute 'name'(父类在__init__中设的属性没被设置) - 父类注册的钩子、资源分配、日志记录等副作用全部丢失
- 多重继承时出现“部分父类未初始化”,后续调用可能崩溃
- 使用
@dataclass或__slots__的类,漏掉super().__init__()会直接报错
super() 不是万能的:什么时候该用父类名显式调用
绝大多数情况应优先用 super(),但以下两个真实场景例外:
- 需要绕过 MRO,**强制调某个特定父类**的方法(比如
A和B都定义了serialize(),你明确只要A.serialize()) - 父类不是当前类的直接父类,而是“祖父类”或更上层,且你不想依赖整个 MRO 链(极少见,通常说明设计有问题)
此时写 A.serialize(self) 比 super().serialize() 更清晰、更可控。但要注意:必须手动传 self,且无法享受 super() 的协作式继承优势。
super()。哪怕只有一处写成 Parent.__init__(self),整个链就断了——这不是语法错误,而是静默失效。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










