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

无法继承datetime.timedelta类的问题咨询及原因排查

如何正确继承Python的datetime.timedelta类?

我之前也踩过这个坑!问题出在timedelta这类C实现的内置不可变类型,实例创建逻辑和普通Python类(比如dict)完全不一样。

先给你拆解问题根源:

  • 像dict这种可变内置类型,__init__是真正负责接收参数、初始化实例内容的入口,所以你继承时重写__init__并调用super().__init__(*args, **kwargs)完全没问题。
  • 但timedelta是不可变类型,它的实例属性(比如days、seconds)是在__new__方法里就初始化完成的,它的__init__方法实际上是空的——既不处理参数,也不接受任何参数。

你写的my_timedelta重写了__init__,并把创建实例时传入的参数传给了super().__init__,但timedelta.__init__根本不接受参数,自然就触发了TypeError: object.__init__() takes no parameters(因为timedelta的__init__最终继承自object的__init__,而object的__init__确实不接受参数)。

那怎么正确继承timedelta呢?分两种情况:

情况1:不需要额外初始化逻辑

直接去掉子类的__init__方法就行!这样创建实例时,参数会直接传给父类的__new__方法,完全正常:

from datetime import timedelta
class my_timedelta(timedelta):
    pass  # 不需要重写__init__

# 测试完全正常
t0 = my_timedelta()
print(t0)  # 0:00:00

t1 = my_timedelta(5)
print(t1)  # 0:00:05

t2 = my_timedelta(seconds=5)
print(t2)  # 0:00:05

情况2:需要添加自定义初始化逻辑

这种情况下你需要重写__new__方法,因为不可变类型的实例属性是在__new__阶段确定的。如果还要保留__init__,注意不要给super().__init__传参数:

from datetime import timedelta
class my_timedelta(timedelta):
    def __new__(cls, *args, **kwargs):
        # 这里可以添加自定义逻辑,比如修改参数
        # 调用父类的__new__创建实例
        instance = super().__new__(cls, *args, **kwargs)
        # 给实例添加自定义属性(timedelta是不可变类型,但子类实例可以添加Python层面的属性)
        instance._custom_note = "这是自定义的timedelta子类"
        return instance

    def __init__(self, *args, **kwargs):
        # 这里写自己的初始化逻辑,不要传参数给super().__init__
        self._another_attr = "额外属性"

# 测试
t = my_timedelta(hours=2, minutes=30)
print(t)  # 2:30:00
print(t._custom_note)  # 这是自定义的timedelta子类

最后再补充一点:所有Python中不可变的内置类型(比如int、str、datetime.date等)的继承逻辑都和timedelta类似,核心就是重写__new__而不是__init__来处理参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:32:56