Счётчик можно хранить в атрибуте функции-обёртки и увеличивать при каждом вызове. Для конкурентных потоков обновление защищают Lock; wraps сохраняет имя и метаданные исходной функции.
Напишите декоратор, который считает кол-во вызовов декорируемых функций
Счётчик можно хранить в атрибуте функции-обёртки и увеличивать при каждом вызове. Для конкурентных потоков обновление защищают Lock; wraps сохраняет имя и метаданные исходной функции.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Напишите декоратор, который считает кол-во вызовов декорируемых функций
Ответ
Счётчик можно хранить в атрибуте функции-обёртки и увеличивать при каждом вызове. Для конкурентных потоков обновление защищают Lock; wraps сохраняет имя и метаданные исходной функции.
Здесь каждая декорированная функция имеет свой счётчик, включая вызовы, завершившиеся исключением:
from functools import wraps
from threading import Lock
def count_calls(func):
lock = Lock()
@wraps(func)
def wrapper(*args, **kwargs):
with lock:
wrapper.calls += 1
return func(*args, **kwargs)
wrapper.calls = 0
return wrapper
После декорирования значение доступно как function.calls. Блокировка не удерживается во время выполнения самой функции. Между отдельными процессами счётчик не общий; для async-функций этот вариант считает создание coroutine, а не завершённые исполнения.