如何覆盖datetime.datetime并保留datetime.date的实例

时间:2017-03-09 10:46:34

标签: python datetime module

我们写了一个覆盖datetime.datetime和datetime.date(见下文)

TEST_TIME_DELTA = datetime.timedelta(seconds=0)

class TimeTravelDateTime(datetime.datetime):
    @classmethod
    def now(cls,*args, **kwargs):
        return super(TimeTravelDateTime,cls).now(*args, **kwargs) +  globals()["TEST_TIME_DELTA"]

    @classmethod
    def utcnow(cls, *args, **kwargs):
        return super(TimeTravelDateTime, cls).utcnow(*args, **kwargs) + globals()["TEST_TIME_DELTA"]


    @classmethod
    def today(cls, *args, **kwargs):
        return super(TimeTravelDateTime, cls).today(*args, **kwargs) + globals()["TEST_TIME_DELTA"]

class TimeTravelDate(datetime.date):
    @classmethod
    def today(cls, *args, **kwargs):
        return super(TimeTravelDate, cls).today(*args, **kwargs) + globals()["TEST_TIME_DELTA"]

然后我们做了以下

sys.modules['datetime'].datetime = TimeTravelDateTime
sys.modules['datetime'].date = TimeTravelDate

但是我们的代码现在每次尝试将relativedelta添加到datetime.datetimes时都会失败,因为在relativedelta add方法的代码中,有一个检查:

if not isinstance(other, datetime.date):
    raise TypeError("unsupported type for add operation") 

其他是datetime.datetime.today()。 默认情况下,datetime.datetime是datetime.date的实例。另外,如果我们覆盖datetime.datetime,则datetime.datetime.today()仍然是datetime.date的一个实例。即使type(datetime.datetime.today())= datetime.datetime

但是随着我们覆盖datetime.date,isinstance检查不再通过。

如果我们只覆盖datetime.datetime,这是有效的,但是一旦我们覆盖datetime.date,一切都会变成地狱。

我们如何覆盖datetime.date,以便datetime.datetime仍然是datetime.date的一个实例。即。保持子类关系从这里https://docs.python.org/2/library/datetime.html#available-types(向下滚动一点点)。

1 个答案:

答案 0 :(得分:0)

我们只使用了freezegun包,并使用https://github.com/spulec/freezegun

重构了我们的测试