You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.7下子类化Pint的Q_类:super调用为何失效?

为什么子类化Pint Quantity调用super会报错?

先看你报错的直接原因——super的参数写错了!你写的是super(Q_, self).__init__(*args, **kwargs),这里的super第一个参数应该传当前子类Q_Child_,而不是父类Q_。

当你传Q_给super时,Python会去找Q_的父类(也就是object)的__init__方法,而object.__init__只接受self这一个参数,你却塞了1.0和's'进去,自然就触发了TypeError。如果把super改成super(Q_Child_, self).__init__(*args, **kwargs),这个报错就会消失。

不过你肯定会好奇:为什么不调用super,子类实例反而能正常工作?这就得说说Pint Quantity和dict在实例化逻辑上的区别了:

1. Pint Quantity靠__new__完成初始化,__init__只是“锦上添花”

Pint的Quantity类是为了处理带单位的数值,它的核心实例化逻辑是在__new__方法里实现的——当你创建Q_Child_(1.0, 's')时,Python首先调用父类Q_的__new__方法,这个方法会接收数值和单位参数,直接创建并返回一个已经完全初始化好的Quantity实例。

等到执行子类的__init__时,实例早就“成型”了,你只需要在这个方法里添加自定义属性(比如self.foo)就行,完全不需要调用父类的__init__——因为它的初始化工作早在__new__阶段就做完了。

2. dict靠__init__填充数据,__new__只造空壳

而dict的实例化逻辑正好相反:__new__方法只会创建一个空的dict对象,真正把传入的键值对填充进去的逻辑是在__init__里实现的。所以如果子类不调用super().__init__,那这个dict就始终是空的,自然看不到你传入的{'a':1}。

总结一下

  • 你报错的直接原因是super的参数写错了,把父类Q_当成了第一个参数,导致调用了object的__init__;
  • 不调用super也能正常工作,是因为Quantity的初始化在__new__阶段就完成了,__init__只是后续添加属性的环节;
  • dict必须调用super的__init__,是因为它的数据填充逻辑在__init__里。

内容的提问来源于stack exchange,提问作者Leporello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:52:58