继承int等不可变类时__init__默认参数报错问题及解决
问题解答
你的推测完全正确——这个问题确实是**继承不可变内置类(如int、str)**导致的。
原因分析
不可变内置类型的实例创建逻辑和普通可变类存在本质差异:
- 不可变类的实例实际在
__new__方法中完成创建,__init__方法几乎不执行任何实质性初始化逻辑,仅作为形式上的接口存在。 - 它们的
__init__方法签名非常严格,不接受任何自定义关键字参数。当你在子类__init__中把包含自定义参数(如你的b)的**kwargs传给super().__init__时,父类无法识别这些参数,直接触发TypeError。
解决办法
针对这种场景,有两种可靠的处理方式:
1. 重写__new__方法(推荐)
既然不可变类的实例创建由__new__负责,我们可以重写该方法来处理自定义参数,同时避免把无关参数传给父类:
class MyClass(int): def __new__(cls, a, *args, b=False, **kwargs): # 仅将父类能识别的参数传给int的__new__,创建实例 instance = super().__new__(cls, *args, **kwargs) # 给实例绑定自定义属性 instance.a = a instance.b = b return instance # 可选:如果需要在__init__中补充逻辑,无需再调用super().__init__ def __init__(self, a, *args, b=False, **kwargs): self.a = a self.b = b
示例调用:obj = MyClass(5, 10, b=True),此时obj的整数数值为10,自定义属性a=5、b=True,不会触发参数错误。
2. 避免向父类__init__传递自定义参数
如果你不需要修改实例的整数数值逻辑,可以直接在子类__init__中跳过传递自定义参数给父类:
class MyClass(int): def __init__(self, a, *args, b=False, **kwargs): # 仅调用父类__init__,不传递任何额外参数(int的__init__不需要参数) super().__init__() self.a = a self.b = b
注意:此时实例的整数数值由*args中的第一个参数决定(比如MyClass(5, 20)会创建数值为20的实例),如果要让实例数值等于a,可以调整__new__逻辑为super().__new__(cls, a)。
内容的提问来源于stack exchange,提问作者user17301834
相关产品推荐
相关产品推荐

