Напишите декоратор, который считает кол-во вызовов декорируемых функций

Счётчик можно хранить в атрибуте функции-обёртки и увеличивать при каждом вызове. Для конкурентных потоков обновление защищают 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, а не завершённые исполнения.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее