在Python中,如何创建datetime.timedelta的子类

时间:2016-11-23 11:21:40

标签: python datetime inheritance

我想通过datetime__div__操作扩展__mod__模块的timedelta对象。我希望生成的类TimeDelta可以使用普通timedelta作为其第一个输入参数,或使用timedelta的常用关键字参数(例如seconds=1)进行初始化。但是,我对以下内容感到困惑:

import datetime

class TimeDelta(datetime.timedelta):
    def __init__(self, timedelta, *args, **kwargs):
        pass

td1 = TimeDelta(datetime.timedelta(seconds=3))

这会导致错误

Traceback (most recent call last):
  File "/home/kurt/dev/scratch/Furion_scheduler/extended_timedelta.py", line 7, in <module>
    td1 = TimeDelta(datetime.timedelta(seconds=3))
TypeError: unsupported type for timedelta days component: datetime.timedelta

,正如Daniel Roseman在earlier answer中指出的那样,是因为timedelta对象定义了__new__方法(参见其source code)。

解决此问题的一种方法是使用合成而不是继承:

class TimeDelta(object):
    def __init__(self, timedelta, *args, **kwargs):
        if isinstance(timedelta, datetime.timedelta):
            self.timedelta = timedelta
        else:
            self.timedelta = datetime.timedelta.__init__(*args, **kwargs)

    def __mod__(self, other):
        if isinstance(other, datetime.timedelta):
            return self.timedelta.total_seconds() % other.total_seconds()
        elif isinstance(other, TimeDelta):
            return self.timedelta.total_seconds() % other.timedelta.total_seconds()

td1 = TimeDelta(datetime.timedelta(seconds=5))
td2 = TimeDelta(datetime.timedelta(seconds=2))

print td1 % td2

然而,一个不那么优雅的方面是,在__mod__方法中,当前必须检查othertimedelta或{{1}的实例}}。

有没有办法让继承工作,或者使TimeDelta具有组合,使得如果没有定义任何调用它的方法(例如TimeDelta),它会尝试调用total_seconds()上的方法?

更新

最后,我发现使用合成比覆盖self.timedelta方法更容易。我通过为__new__定义total_seconds()方法来重构上面的代码:

TimeDelta

如果class TimeDelta(object): def __init__(self, timedelta=None, **kwargs): if isinstance(timedelta, datetime.timedelta): self.timedelta = timedelta else: self.timedelta = datetime.timedelta(**kwargs) def total_seconds(self): return self.timedelta.total_seconds() def __mod__(self, other): return self.total_seconds() % other.total_seconds() 有许多必须被引用的方法,这种方法会很麻烦。以这种方式,但在这种情况下timedelta是唯一的方法(参见https://docs.python.org/2/library/datetime.html#datetime.timedelta)。

0 个答案:

没有答案