从函数内部禁用`functools.lru_cache`

时间:2019-06-11 12:59:27

标签: python python-decorators functools

我想要一个可以使用functools.lru_cache的功能,但默认情况下不可以。我正在寻找一种使用函数参数的方法,该函数参数可用于禁用lru_cache。当前,我有该函数的两个版本,一个带有lru_cache,另一个没有。然后我有另一个函数,用一个参数将它们包装起来,该参数可以用来控制使用哪个函数

def _no_cache(foo):
    print('_no_cache')
    return 1


@lru_cache()
def _with_cache(foo):
    print('_with_cache')
    return 0


def cache(foo, use_cache=False):
    if use_cache:
        return _with_cache(foo)
    return _no_cache(foo)

有更简单的方法吗?

2 个答案:

答案 0 :(得分:1)

您不能从装饰函数内部禁用缓存。但是,您可以通过直接通过__wrapped__属性访问该函数来简化代码。

来自documentation

  

原始基础功能可通过__wrapped__访问   属性。这对于自省,绕过缓存很有用,   或用于使用其他缓存重新包装功能。

演示:

from functools import lru_cache

@lru_cache()
def f(arg):
    print(f"called with {arg}")
    return arg    

def call(arg, use_cache=False):
    if use_cache:
        return f(arg)
    return f.__wrapped__(arg)

call(1)
call(1, True)
call(2, True)
call(1, True)

输出:

called with 1
called with 1
called with 2

答案 1 :(得分:0)

要进行检查,可以使用包装函数的cache_info()方法:

from functools import lru_cache

@lru_cache()
def my_function(foo):
    return foo * 2

def cache(foo, use_cache=False):
    if use_cache is False:
        return my_function.__wrapped__(foo)
    return my_function(foo)

print(cache(10, use_cache=True))    # cache miss
print(cache(10, use_cache=True))    # cache hit
print(cache(10, use_cache=False))   # bypass
print(cache(20, use_cache=False))   # bypass

print(my_function.cache_info())     # cache size=1, hit=1, miss=1

打印:

20
20
20
40
CacheInfo(hits=1, misses=1, maxsize=128, currsize=1)