无法继承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
相关产品推荐
相关产品推荐

