继承Decimal类自定义构造函数参数时遇TypeError问题求助
继承Decimal类自定义构造函数报错的解决方案
问题重现
尝试继承decimal.Decimal并新增构造参数时,编写了如下代码:
from decimal import Decimal class MyDecimal(Decimal): def __init__(self, value, dummy): super().__init__(value) print(dummy) x = MyDecimal(5, 'test')
运行后抛出错误:
TypeError: optional argument must be a context
问题原因
Decimal是不可变数值类型,它的实例创建逻辑由__new__方法负责,而非__init__。当调用MyDecimal(5, 'test')时,Python会先调用父类的__new__方法,此时第二个参数'test'会被Decimal的__new__误认为是context参数(该参数要求是decimal.Context类型),因此触发类型错误。
解决方案
需要重写__new__方法,先过滤掉自定义的额外参数,再调用父类的__new__创建实例,之后再处理自定义参数的逻辑。
基础示例代码
from decimal import Decimal class MyDecimal(Decimal): def __new__(cls, value, dummy): # 调用父类__new__创建实例,仅传入value参数 instance = super().__new__(cls, value) # 将dummy绑定到实例,或直接执行对应逻辑 instance.dummy = dummy print(dummy) return instance # 测试 x = MyDecimal(5, 'test') print(x) # 输出: 5 print(x.dummy) # 输出: test
兼容context参数的写法
如果需要支持传递Decimal原生的context参数,可以通过可变参数扩展:
from decimal import Decimal, getcontext class MyDecimal(Decimal): def __new__(cls, value, dummy, *args, **kwargs): instance = super().__new__(cls, value, *args, **kwargs) instance.dummy = dummy print(dummy) return instance # 带context参数的调用示例 ctx = getcontext() x = MyDecimal(5, 'test', ctx)
总结
对于Python中的不可变类型(如Decimal、int、str等),自定义子类时需要重写__new__方法来处理额外参数,而非仅重写__init__,否则会导致父类的实例创建逻辑接收到不符合要求的参数,引发错误。
内容的提问来源于stack exchange,提问作者user16004728
相关产品推荐
相关产品推荐

