Задание из Яндекс Практикума по Python, Декораторы
"Задание: Напишите функцию-декоратор, которая сохранит (закеширует) значение декорируемой функции. Если декорируемая функция будет вызвана повторно с теми же параметрами — декоратор должен вернуть сохранённый результат, не выполняя функцию.
Подсказка: Создайте словарь и при каждом вызове декоратора сохраняйте в нём аргументы задекорированной функции. При каждом вызове проверяйте, не было ли уже аналогичного вызова. Если был — верните результат прошлого вызова, если не было — верните результат декорируемой функции и одновременно сохраните этот результат в словарь. Ключом для каждой записи словаря может быть аргумент декорируемой функции."
Собственно, код. Написать требуется функцию cache_args, но как ни бьюсь — она работает неверно.
import time
from functools import wraps
def time_check(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
execution_time = round(time.time() - start_time, 1)
print(f'Время выполнения функции {func.__name__}: {execution_time} с.')
return result
return wrapper
def cache_args(func):
@wraps(func)
def wrapper1(*args, **kwargs):
result = func(*args, **kwargs)
x = []
for t in x:
if t == result:
return t
x = x.append(result)
return result
return wrapper1
@time_check
@cache_args
def long_heavy(num):
time.sleep(1)
return num * 2
print(long_heavy(1))
# Время выполнения функции long_heavy: 1.0 с.
# 2
print(long_heavy(1))
# Время выполнения функции long_heavy: 0.0 с.
# 2
print(long_heavy(2))
# Время выполнения функции long_heavy: 1.0 с.
# 4
print(long_heavy(2))
# Время выполнения функции long_heavy: 0.0 с.
# 4
print(long_heavy(2))
# Время выполнения функции long_heavy: 0.0 с.
# 4
Ответы (2 шт):
cache = {}
def cache_args(func):
@wraps(func)
def wrapper1(*args, **kwargs):
if args[0] in cache:
return cache[args[0]]
else:
result = func(*args, **kwargs)
cache[args[0]] = result
return result
return wrapper1
Я написал чуть короче:
cache = {}
def cache_args(func):
@wraps(func)
def wrapper(*args, **kwargs):
if args not in cache:
cache[args] = func(*args, **kwargs)
return cache[args]
return wrapper
Возможно это и не очень грамотно с точки зрения реальных проектов, но для решения учебной задачи ИМХО достаточно.