freeze_time не работает для параметра по умолчанию - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть функция со значением по умолчанию параметра как datetime.now().Метод выглядит примерно так:

def as_standard_format(p_date=datetime.now(), fmt=sdk_constants.DEFAULT_DATE_TIME_FORMAT):
    return p_date.strftime(fmt)

И у меня есть метод теста, описанный ниже,

@freeze_time(datetime(year=2018, month=9, day=25, hour=15, minute=46, second=36))
def testNowWithDefaultFormat(self):

    # The below method gives the frozen time
    print(datetime.now())

    # But the below test fails
    assert utils.format_date(
        datetime.now()) == "20180925T154636Z", "Default call not giving current time in " \
                                               "standard format \"%Y%m%dT%H%M%SZ\""

Почему freeze_time не работает со значением параметра по умолчанию?

1 Ответ

0 голосов
/ 28 февраля 2019

Вы являетесь жертвой общей ошибки в Python, связанной с изменяемыми параметрами по умолчанию, а не только с freeze_time.

Для объяснениярассмотрим следующий код:

import time from datetime import datetime

def what_time_is_it(p_date=datetime.now()):
    return p_date.strftime('"%Y-%m-%d %X"')

if __name__ == '__main__':
    print(what_time_is_it())
    time.sleep(10)
    print(what_time_is_it())

То, что вы могли ожидать, произойдет

"2019-02-28 13:47:24"
"2019-02-28 13:47:34" # This line showing a datetime 10 seconds after the first one

Новый datetime.now() вызывается при каждом вызове what_time_is_it()

Что происходит

"2019-02-28 13:47:24"
"2019-02-28 13:47:24" # EXACTLY the same time in both lines!

Новый datetime.now() создается один раз при определении функции, и одно и то же значение используется в каждом последующем вызове.

Что вы должны сделать вместо этого?

Создавать новый объект каждый раз, когда вызывается функция, используя аргумент по умолчанию, указывающий, что аргумент не был предоставлен ( Нет часто является хорошим выбором):

def as_standard_format(p_date=None, fmt=sdk_constants.DEFAULT_DATE_TIME_FORMAT):
    if p_date is None:
        return datetime.now().strftime(fmt)
    else:
        return p_date.strftime(fmt)
...