Выполните generate_list = time_logger(generate_list). Это эквивалентно декоратору @time_logger над определением функции.
Ручная обертка декоратора
Выполните generate_list = time_logger(generate_list). Это эквивалентно декоратору @time_logger над определением функции.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Показать, как вручную обернуть функцию generate_list декоратором time_logger, не используя синтаксис @time_logger, а вызывая декоратор явно.
import time
def time_logger(func):
def wrapped(*args, **kwargs):
t_start = time.time()
result = func(*args, **kwargs)
t_end = time.time()
print(f'func ran in {t_end - t_start}')
return result
return wrapped
def generate_list(count: int) -> list[int]:
return [i for i in range(count)]
# ручное применение декоратора
generate_list = time_logger(generate_list)
Ответ
Выполните generate_list = time_logger(generate_list). Это эквивалентно декоратору @time_logger над определением функции.
После присваивания имя generate_list указывает на обёртку, а исходная функция сохранена в её замыкании:
generate_list = time_logger(generate_list)
result = generate_list(3) # [0, 1, 2] и сообщение о времени.
Само применение декоратора не запускает вычисление; измерение происходит при последующем вызове. Если нужно сохранить доступ к исходной версии, присвойте обёртку другому имени.
Для измерения длительности предпочтительнее time.perf_counter(), не зависящий от коррекции календарных часов. functools.wraps сохранит имя и документацию функции. В исходном варианте при исключении сообщение о времени не выводится; finally нужен, если его требуется печатать всегда.