Увеличивайте счётчик только после успешного возврата функции. Если она выбросила исключение, управление до увеличения не дойдёт. Счётчик можно хранить атрибутом обёртки.
Создание декоратора для подсчёта успешных вызовов функции
Увеличивайте счётчик только после успешного возврата функции. Если она выбросила исключение, управление до увеличения не дойдёт. Счётчик можно хранить атрибутом обёртки.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Разработайте декоратор, который будет вести учёт количества успешных вызовов функции. Под успешным вызовом подразумевается ситуация, когда функция завершает работу без генерации исключения.
Ответ
Увеличивайте счётчик только после успешного возврата функции. Если она выбросила исключение, управление до увеличения не дойдёт. Счётчик можно хранить атрибутом обёртки.
Пример для синхронной функции с защитой самого счётчика:
from functools import wraps
from threading import Lock
def count_successes(func):
lock = Lock()
@wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
with lock:
wrapper.success_count += 1
return result
wrapper.success_count = 0
return wrapper
Результат False или None тоже считается успехом, если исключения нет. Lock не сериализует выполнение функции, только обновление числа. Это локальная статистика процесса. Для async-функций считать нужно после await, а не после создания объекта корутины.