为何将类实例作为基类时会报‘Foo() takes no arguments’错误?
为什么Python继承类实例会触发「Foo() takes no arguments」错误?
先看触发错误的代码:
>>> class Foo: pass >>> class Spam(Foo()): pass
运行后会抛出如下错误:
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Foo() takes no arguments
错误根源与执行流程拆解
Python规定类继承的父类必须是类对象,不能是类的实例。当你写Spam(Foo())时,整个执行流程是这样的:
- 先执行
Foo(),成功创建一个Foo类的实例; - 接下来Python尝试创建Spam类,把刚才的Foo实例当作父类传入元类的构造逻辑(所有用户定义类默认由
type元类创建,底层会调用type('Spam', (Foo实例,), {})); - 元类在处理继承关系时,需要父类是可被用于构建类层级的类对象,但传入的是实例。此时底层会尝试对这个实例执行类相关的操作,其中涉及到调用该实例(类似函数调用),但Foo类没有定义
__call__方法,实例本身不支持被调用,于是就抛出了「Foo() takes no arguments」这个看似误导的错误——错误信息里的Foo()其实指的是尝试调用Foo的实例,而非创建Foo实例的过程。
简单总结:错误的本质是实例不能作为父类被继承,而报错信息的表述容易让人误解成创建Foo实例时出了问题,但实际上Foo实例已经成功创建了,问题出在后续用实例当父类的元类处理环节。
内容的提问来源于stack exchange,提问作者yixuan
相关产品推荐
相关产品推荐

