0

Есть много украшений для заметок, но мне любопытно, как можно написать декоратор memoization, который поддерживает произвольные сигнатуры функций, но позволяет функции решить, когда memoize результат? Что-то вроде этого:Условная память?

def conditional_memoize(f): 
    cache = {} 
    @wraps(f) 
    def conditional_f(*args, **kwargs): 
     return f(*args, **kwargs) 
    return conditional_f 

@conditional_memoize 
def my_func(a, b, c): 
    if str(a) + str(b) + str(c) in cache: 
     return cache[str(a) + str(b) + str(c)] 
    res = # compute the result 
    if some_arbitrary_condition: 
     cache[str(a) + str(b) + str(c)] = res 
    return res 

Однако, я знаю, что это не будет работать из-за NameError. Есть ли умный подход к проблеме в любом случае? Я всегда мог использовать метод класса и кеш-класс, просто хотел посмотреть, есть ли для этого шаблон декоратора.

+0

Как функция должна сообщать о своем желании получить кеш-результат или нет? – martineau

ответ

1

Имейте функцию, возвращающую как ее желаемый результат, так и флаг, указывающий, должен ли быть получен кеш-файл или иметь оболочку, передающую объект кеша функции. (Или и то и другое!) В любом случае это сработает, но мне лучше нравится первый подход. Может быть, что-то вроде этого ...

+0

Это эффективно изменяет результат, который возвращает украшенная функция, что означает, что они должны быть написаны с предположением, что они будут украшены. – martineau

+0

Несомненно. Конечно, это не обязательно проблема; существует множество декораторов, которые требуют таких предположений. – kindall

+0

Это предположение действительно актуально. Передача объекта кеша в функцию тоже в порядке. Хотелось бы, чтобы у меня была какая-то предикатная логика. Хотел бы я написать Пролог. – 2rs2ts