Ограничитель частоты вызова произвольной функции

Храните время последнего допущенного вызова по monotonic и проверяйте интервал под Lock. wraps сохраняет метаданные и исходную сигнатуру для стандартной интроспекции.

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

Что ответить на собеседовании

Храните время последнего допущенного вызова по monotonic и проверяйте интервал под Lock. wraps сохраняет метаданные и исходную сигнатуру для стандартной интроспекции.

Подробный разбор

Ответ с пояснениями

Условие

Создайте декоратор, который ограничивает частоту вызовов любой функции. Период ограничения (в секундах) передаётся в сам декоратор как аргумент. Если попытаться вызвать функцию до истечения указанного периода, должен быть сгенерирован исключительный тип CalledTooOftenError. Декоратор обязан корректно работать с функциями любой сигнатуры и сохранять их оригинальное объявление.

def foo():
    print('foo')

Ответ

Храните время последнего допущенного вызова по monotonic и проверяйте интервал под Lock. wraps сохраняет метаданные и исходную сигнатуру для стандартной интроспекции.

from functools import wraps
from threading import Lock
from time import monotonic

class CalledTooOftenError(Exception):
    pass

def rate_limit(period):
    if period < 0:
        raise ValueError('Период не может быть отрицательным')
    def decorate(func):
        guard = Lock()
        last = None
        @wraps(func)
        def wrapper(*args, **kwargs):
            nonlocal last
            with guard:
                now = monotonic()
                if last is not None and now - last < period:
                    raise CalledTooOftenError()
                last = now
            return func(*args, **kwargs)
        return wrapper
    return decorate

Интервал отсчитывается между началами допущенных вызовов, включая завершившиеся ошибкой. Блокировка не удерживается во время работы функции. Ограничитель общий для этой обёртки в одном процессе; для нескольких узлов нужно общее хранилище. Async-функциям нужен отдельный вариант, проверяющий лимит при выполнении корутины.

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

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

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

Подробнее