Кеширующий декоратор: замыкание и сохранение None, 0, False

Создайте отдельный словарь в замыкании декоратора и сохраняйте результат по ключу аргументов. Проверка наличия ключа, а не истинности результата, позволяет кешировать None, 0 и False.

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

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

Создайте отдельный словарь в замыкании декоратора и сохраняйте результат по ключу аргументов. Проверка наличия ключа, а не истинности результата, позволяет кешировать None, 0 и False.

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

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

Условие

Написать код для функции cache. Это декоратор, который должен

запоминать, что вернула декорированная функция, и возвращать запомненное

значение при повторном вызове с одинаковыми аргументами.

Можно считать, что все аргументы хешируемые.

Использовать только стандартную библиотеку Python.

def cache(func): raise NotImplementedError

calls = {"count": 0}

@cache def add(a, b): calls["count"] += 1 return a + b

assert add(1, 2) == 3 assert calls["count"] == 1

assert add(1, 2) == 3 assert calls["count"] == 1

assert add(2, 3) == 5 assert calls["count"] == 2

print("OK")

Ответ

Создайте отдельный словарь в замыкании декоратора и сохраняйте результат по ключу аргументов. Проверка наличия ключа, а не истинности результата, позволяет кешировать None, 0 и False.

from functools import wraps

def cache(func):
    values = {}
    @wraps(func)
    def wrapped(*args, **kwargs):
        key = (args, tuple(sorted(kwargs.items())))
        if key not in values:
            values[key] = func(*args, **kwargs)
        return values[key]
    return wrapped

Для тестов из условия счётчик будет равен 2. Ошибки не кешируются. Эквивалентные позиционные и именованные вызовы могут получить разные ключи. В production учитывайте ограничение размера, изменяемые результаты и конкурентный доступ; для простых случаев есть functools.cache.

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

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

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

Подробнее