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

继承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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:24:45