应将所有参与多继承的类的__init__方法改为keyword-only参数形式,即def __init__(self, , arg1, arg2, kwargs),并统一用super().__init__(kwargs)透传,确保MRO链中每个类都显式声明所需参数且不残留未处理的*kwargs。

super() 报 TypeError: object.__init__() takes exactly one argument 怎么修
这是最常遇到的报错,说明参数最终传到了 object.__init__(),而它只接受 self。根本原因是:某个父类没把自己声明的参数“消化干净”,导致剩余 **kwargs 还带着键值对往下传,直到撞上 object。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 查出 MRO 链中最后一个非
object的类(比如D(A, B).mro()是[D, A, B, object],那就要盯紧B) - 确认该类的
__init__是否显式声明了所有它要接收的参数,并用*隔开,例如def __init__(self, *, price, currency, **kwargs) - 如果它不处理任何业务参数,也得写成
def __init__(self, **kwargs)并调用super().__init__(**kwargs),不能省略 - 检查是否误传了该类未声明的 key,比如传了
city但类里只写了price和currency,那city就会残留在**kwargs里
为什么 super().__init__(country, city) 会报 missing keyword-only argument
因为参数位置错位了——super() 不是按你写的顺序传参,而是按 MRO 顺序逐级分发。一旦某一级没用 * 声明 keyword-only 参数,它就会把第一个 positional 参数当成自己的,后面类收到的 **kwargs 就缺东西。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 所有参与多继承的类,只要带初始化参数,
__init__必须写成def __init__(self, *, arg1, arg2, **kwargs),绝不能是def __init__(self, arg1, arg2, **kwargs) -
super().__init__(**kwargs)是唯一安全写法;显式列出参数(如super().__init__(country, city))会破坏协作式初始化,MRO 一变就崩 - 哪怕某个类只做日志或验证,也要接收
**kwargs并透传,否则链条在它这儿就断了
TypeError: super() argument 1 must be type, not classobj 是什么问题
这是 Python 2 的遗留问题,或你在 Python 3 里定义了经典类(即没显式继承 object)。super() 只支持新式类,而新式类必须直接或间接继承 object。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 确保所有基类都继承
object,比如写成class Publisher(object):,而不是class Publisher: - Python 2 环境下无法用
super()无参形式,必须写全super(ClassName, self),且ClassName必须是新式类 - Python 3 中默认所有类都是新式类,但如果你从第三方库继承了一个没继承
object的类,仍可能触发此错
怎么验证 MRO 是否合理、super 调用是否按预期走
别猜,直接看。MRO 不是你写的顺序,C3 算法算出来的结果才是真实执行路径。很多报错本质是预期和实际 MRO 对不上。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 运行
MyClass.mro(),把结果复制出来一行行对照,确认你想调用的父类是否真在链上、位置是否符合逻辑 - 在每个
__init__开头加print(f"{self.__class__.__name__} got {kwargs}"),观察参数如何被逐级取走 - 如果
MyClass.mro()报Cannot create a consistent method resolution order,说明继承结构非法,得重构——比如两个父类有共同祖先,但在各自 MRO 中祖先出现顺序不一致
真正麻烦的不是写错一行 super(),而是多个类对参数的“消费”边界模糊。只要有一个类没用 * 隔开参数,整个链就不可靠。协作式初始化的前提,是所有人遵守同一套契约:只拿自己声明的,剩下的原样交出去。


















