Отслеживать количество вызовов функции с помощью декоратора можно, создав декоратор, который будет инкапсулировать исходную функцию и хранить счетчик вызовов. При каждом вызове обернутой функции, счетчик будет увеличиваться.
Пример реализации:
import functools
def call_counter(func):
"""Декоратор, отслеживающий количество вызовов функции."""
@functools.wraps(func)
def wrapper(*args, **kwargs):
wrapper.calls += 1
return func(*args, **kwargs)
wrapper.calls = 0
return wrapper
@call_counter
def my_function(x):
"""Пример функции, которую нужно отслеживать."""
return x * 2
print(my_function(5)) # Output: 10
print(my_function(10)) # Output: 20
print(f"Функция my_function была вызвана {my_function.calls} раз(а).") # Output: Функция my_function была вызвана 2 раз(а).
Разъяснение кода:
call_counter(func)
: Это функция-декоратор. Она принимает функцию func
в качестве аргумента.@functools.wraps(func)
: Этот декоратор из модуля functools
сохраняет метаданные исходной функции (имя, docstring и т.д.). Это важно для правильной работы introspection и отладки.wrapper(*args, **kwargs)
: Это функция-обертка, которая заменяет исходную функцию. Она принимает произвольное количество позиционных и именованных аргументов, чтобы можно было применять декоратор к любой функции.wrapper.calls += 1
: При каждом вызове wrapper
, счетчик wrapper.calls
увеличивается на 1.return func(*args, **kwargs)
: Вызывает исходную функцию с переданными аргументами и возвращает результат.wrapper.calls = 0
: Инициализирует атрибут calls
у функции-обертки wrapper
нулем. Этот атрибут будет хранить количество вызовов.@call_counter
: Применение декоратора call_counter
к функции my_function
.Преимущества использования декораторов в данном случае: