条件记忆?

问题描述 投票:0回答:2

有很多记忆化装饰器,但我很好奇如何编写一个支持任意函数签名的记忆化装饰器,但让函数决定何时记忆结果?像这样的东西:

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
。无论如何,有一个聪明的方法来解决这个问题吗?我总是可以使用类方法和类缓存,只是想看看是否有一个装饰器模式。

python decorator python-2.6 memoization python-decorators
2个回答
2
投票

让函数返回其所需的结果和指示是否应缓存结果的标志,或者让包装器将缓存对象传递给函数。 (或两者兼而有之!)无论哪种方式都可以,但我更喜欢第一种方法。也许是这样的......

import functools

def conditional_memoize(fn):
    cache = {}

    @functools.wraps(fn)
    def wrapper(*args, **kwargs):
        key = args + tuple(sorted(kwargs.iteritems()))
        if key in cache:
            return cache[key]
        result, flag = fn(*args, **kwargs)
        if flag:
            cache[key] = result
        return result

    return wrapper

0
投票

有一个名为 conditional-cache 的库提供了此功能。 有两种方法可以根据您的用例调整缓存。最常见的一种是根据输出进行缓存。例如:

from conditional_cache import lru_cache

# For example, if your condition is that the result is even
some_arbitrary_condition = lambda func_result: func_result % 2 = 0    

@lru_cache(condition=some_arbitrary_condition)
def my_func(a, b, c):
    res = # compute the result
    return res

这样,只有当

condition
函数求值
True
时,结果才会被缓存。

或者,如果您的条件仅取决于输入,您可以做的是在调用后删除该元素缓存。例如:

from conditional_cache import lru_cache

some_arbitrary_condition = lambda a, b, c: (a + b - c) == 0

@lru_cache
def my_func(a, b, c):
    res = # compute the result
    return res

if some_arbitrary_condition(a, b, c):
    my_func.cache_remove(a=a, b=b, c=c)

安装:

pip install conditional-cache
© www.soinside.com 2019 - 2024. All rights reserved.