Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Python: decorator, closure, nonlocal

Как написать декоратор, который считает количество вызовов произвольной функции и при превышении заданного лимита выбрасывает исключение?

Этот вопрос проверяет понимание декораторов, замыканий и управления состоянием между вызовами функции.

Короткий ответ

Короткий ответ (3–6 предложений)

Декоратор — это функция, которая оборачивает другую функцию и может изменять её поведение. Чтобы считать количество вызовов, нужно сохранить счётчик во внешней области видимости (замыкание). При каждом вызове счётчик увеличивается, и если он превышает лимит, выбрасывается исключение. Такой подход часто используется для ограничения доступа, защиты ресурсов или отладки.

Длинный ответ

Декораторы позволяют добавить логику до и после выполнения функции, не изменяя её код напрямую.

Определение

Определение: Декоратор — это функция, которая принимает другую функцию и возвращает новую функцию с расширенным или изменённым поведением.

Идея решения

Нам нужно:

  1. Передать лимит вызовов в декоратор

  2. Хранить счётчик между вызовами

  3. Проверять лимит при каждом вызове

Для этого используется:

  • Функция-декоратор с аргументами

  • Замыкание для хранения состояния

Пример реализации

def call_limit(max_calls):
    def decorator(func):
        calls = 0

        def wrapper(*args, **kwargs):
            nonlocal calls
            calls += 1
            if calls > max_calls:
                raise RuntimeError("Превышен лимит вызовов функции")
            return func(*args, **kwargs)

        return wrapper
    return decorator

Пример использования

@call_limit(3)
def hello():
    print("Hello")

hello()
hello()
hello()
hello()  # здесь будет исключение

Почему здесь используется nonlocal

  • Переменная calls объявлена во внешней функции decorator

  • Ключевое слово nonlocal позволяет изменять её значение внутри wrapper

Где применяется на практике

  • Ограничение количества попыток (rate limit)

  • Защита от повторных вызовов

  • Отладка и сбор статистики

Вывод

  • Декораторы удобны для добавления счётчиков и ограничений без изменения бизнес-логики.

  • Замыкания позволяют хранить состояние между вызовами функции.

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    5

  • Сложность:

    6

Навыки

  • Python

    Python

Ключевые слова

#decorator

#closure

#nonlocal

Подпишись на Python Developer в телеграм

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.