Сделайте фабрику декоратора с единицей времени и измеряйте интервал через time.perf_counter(). Для миллисекунд умножайте секунды на 1000; finally позволит записать длительность и при исключении.
Декоратор, измеряющий длительность выполнения функции в заданных единицах
Сделайте фабрику декоратора с единицей времени и измеряйте интервал через time.perf_counter(). Для миллисекунд умножайте секунды на 1000; finally позволит записать длительность и при исключении.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо реализовать декоратор, принимающий параметр — единицу измерения времени (например, "ms" или "s") — и выводящий в лог продолжительность работы функции в указанной единице.
import time
def time_duration_unit():
pass
@time_duration_unit("ms")
def work_function():
print("start work function work function")
time.sleep(2)
print("end work function. work function")
work_function()
Ответ
Сделайте фабрику декоратора с единицей времени и измеряйте интервал через time.perf_counter(). Для миллисекунд умножайте секунды на 1000; finally позволит записать длительность и при исключении.
Пример для синхронной функции:
import logging
import time
from functools import wraps
logger = logging.getLogger(__name__)
def time_duration_unit(unit):
factor = {'s': 1, 'ms': 1000}[unit]
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
started = time.perf_counter()
try:
return func(*args, **kwargs)
finally:
elapsed = (time.perf_counter() - started) * factor
logger.info('%s: %.3f %s', func.__name__, elapsed, unit)
return wrapper
return decorate
Неизвестная единица отклоняется при декорировании. Логирование нужно настроить в приложении. Для work_function результат будет около 2000 мс, не обязательно ровно столько; async-функции требуют обёртки с await.