Исходный декоратор проходит пример с add, но не кеширует результат None и может смешивать разные функции в общем backend. Используйте проверку наличия ключа и пространство имён функции.
Общий backend кеша: None и пространство имён функций
Исходный декоратор проходит пример с add, но не кеширует результат None и может смешивать разные функции в общем backend. Используйте проверку наличия ключа и пространство имён функции.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Написать код для функции cache. Это декоратор, который должен
запоминать, что вернула декорированная функция, и возвращать запомненное
значение при повторном вызове с одинаковыми аргументами.
Можно считать, что все аргументы хешируемые.
Использовать только стандартную библиотеку Python.
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) if result is not None: 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")
Ответ
Исходный декоратор проходит пример с add, но не кеширует результат None и может смешивать разные функции в общем backend. Используйте проверку наличия ключа и пространство имён функции.
from functools import wraps
def cache(backend=None):
if backend is None:
backend = {}
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
key = (func, args, tuple(kwargs.items()))
if key in backend:
return backend[key]
result = func(*args, **kwargs)
backend[key] = result
return result
return wrapper
return decorator
Порядок keyword-аргументов сохраняется, поскольку функция с **kwargs может его наблюдать; эквивалентные варианты вызова не нормализуются. Пример предполагает чистую синхронную функцию и локальный словарь. Исключения не кешируются, а mutable-результат возвращается тем же объектом. Для конкурентности, TTL и ограничения памяти нужны дополнительные правила.