Перевёрнутая проверка sentinel в кеше Python

Проверка sentinel перевёрнута: возвращать result нужно при result is not _SANTINEL. Сейчас первый вызов возвращает служебный объект вместо вычисления, поэтому первый assert падает.

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

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

Проверка sentinel перевёрнута: возвращать result нужно при result is not _SANTINEL. Сейчас первый вызов возвращает служебный объект вместо вычисления, поэтому первый assert падает.

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

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

Условие

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

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

_SANTINEL = object()

def cache(backend=None): if backend is None: backend = {} def decorator(func): def wrapper(*args, **kwargs): key = (args, tuple(sorted(kwargs.items()))) result = backend.get(key, _SANTINEL) if result is _SANTINEL: return result result = func(*args, **kwargs) backend[key] = result return result return wrapper return decorator

calls = {"count": 0} backend = {}

@cache(backend=backend) 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 len(backend) == 1 print("OK")

Ответ

Проверка sentinel перевёрнута: возвращать result нужно при result is not _SANTINEL. Сейчас первый вызов возвращает служебный объект вместо вычисления, поэтому первый assert падает.

from functools import wraps

_SENTINEL = object()

def cache(backend=None):
    if backend is None:
        backend = {}
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            key = (args, tuple(sorted(kwargs.items())))
            result = backend.get(key, _SENTINEL)
            if result is not _SENTINEL:
                return result
            result = func(*args, **kwargs)
            backend[key] = result
            return result
        return wrapper
    return decorator

Проверка backend is None сохраняет переданный пустой словарь. Для общего backend нескольких функций нужен отдельный namespace в ключе, иначе одинаковые аргументы столкнутся. Для данного примера одной функции после двух вызовов остаётся одна запись.

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

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

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

Подробнее