super()调用父类方法失败的主因是父类未定义该方法、拼写错误或在类体顶层误用;必须在实例/类方法内调用,且需确认MRO中父类存在并已实现该方法。

super() 调用父类方法时找不到对应函数?
常见错误是 super() 返回的对象没有你要调用的方法,比如父类没定义该方法、拼写错误,或在类定义体中(而非方法内)误用了 super()。Python 不会在运行时动态补全父类方法,它只按 MRO(方法解析顺序)向上查找。确认父类确实实现了该方法,并且你是在子类的实例方法或类方法中调用——super() 在类体顶层直接使用会报 RuntimeError: super(): no arguments。
正确姿势:
- 必须在方法内部调用,如
__init__、save等 - 检查 MRO:打印
Cls.__mro__确认父类在搜索路径中 - 若父类是
object,则不能调用不存在的方法(如super().process()会报AttributeError)
super(self.__class__, self) 和 super() 写法有啥区别?
在普通实例方法中,super() 等价于 super(CurrentClass, self),但不等价于 super(self.__class__, self)。后者在多重继承 + 类被进一步继承时可能出错:如果子类 B 继承 A,而 A 中写了 super(self.__class__, self),那么当 C 继承 B 时,self.__class__ 是 C,super(C, self) 会跳过 B 直接找 C 的上一个父类,破坏链式调用预期。
所以务必用无参 super() —— 它由 Python 在编译时自动绑定当前定义所在类和第一个参数,安全可靠。
- ✅ 推荐:
super().method_name() - ❌ 危险:
super(self.__class__, self).method_name() - ⚠️ 仅限特殊场景:
super(ParentClass, self)(如需强制跳过某层)
重写 __init__ 时忘记调用 super().__init__() 导致父类初始化失效
这是最常踩的坑:子类自定义了 __init__ 却没显式调用父类构造器,结果父类设置的属性(如 self.name、self.config)根本没生成,后续调用直接 AttributeError。尤其在使用第三方库基类(如 django.db.models.Model、unittest.TestCase)时,漏掉 super().__init__() 常导致静默失败或行为异常。
实操建议:
- 只要子类定义了
__init__,第一行优先写super().__init__(*args, **kwargs) - 如果父类
__init__有必填参数,必须传入;不确定时查文档或源码 - 用 IDE 的 “Override method” 功能生成骨架,能自动带出
super()调用
多继承下 super() 如何保证所有父类 __init__ 都执行?
super() 不是简单“调上一级”,而是遵循 C3 线性化 MRO 顺序,协同各层共同完成一次完整的初始化链。前提是所有类都遵守约定:每个 __init__ 都以 super().__init__() 结尾(或至少转发)。一旦某个中间类忘了调 super(),链条就断了,后面的父类不会被执行。
例如 A ← B ← C(C 继承 B,B 继承 A),若 B 的 __init__ 没写 super(),那么 C 实例化时 A 的初始化永远不会触发。
- 验证方式:在各父类
__init__中加print(f"Init {self.__class__.__name__}") - 关键原则:协作式设计 —— 每个类只负责自己那部分初始化,然后把接力棒交给下一个
- 不推荐手动列出所有父类调用,既脆弱又违背 Python 的继承哲学
真正难的不是写对 super(),而是确保整个继承链上的每个类都参与协作。一旦有人绕过规则直接调用 Parent.__init__(self),整条链就不可靠了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











