缓存特殊电话

问题描述

如何从lru_cache更改修饰器functools的行为,以便修饰的函数具有一个标志,该标志指示是否缓存此调用
例如

@new_lru_cache
def f(args,kwargs):
    ...body function...

f(1) # not saved
f(2,cache=True) # saved

解决方法

考虑这一点-扩展lru_cache,允许访问以配置缓存。

from functools import lru_cache

def controlled_lru_cache(*lru_args,**lru_kwargs):
    def decorator(func):
        func_with_cache = lru_cache(*lru_args,**lru_kwargs)(func)
        def decorated(*args,cache=False,**kwargs):
            if cache:
                return func_with_cache(*args,**kwargs) 
            return func(*args,**kwargs)
        return decorated
    return decorator

@controlled_lru_cache(maxsize=64)
def square(n):
    return n * n
,

如果要为其编写一个完整的函数,为什么不复制粘贴原始源代码并在其中实现逻辑呢?

def lru_cache(maxsize=128,typed=False,cache=False):
    if isinstance(maxsize,int):
        if maxsize < 0:
            maxsize = 0
    elif callable(maxsize) and isinstance(typed,bool):
        user_function,maxsize = maxsize,128
        wrapper = _lru_cache_wrapper(user_function,maxsize,typed,_CacheInfo)
        return update_wrapper(wrapper,user_function)
    elif maxsize is not None:
        raise TypeError('Expected first argument to be an integer,a callable,or None')

    def decorating_function(user_function):
        if not cache:
            return user_function # We add here
        wrapper = _lru_cache_wrapper(user_function,user_function)

    return decorating_function

通过这种方式,您可以进一步控制该功能,并且可以轻松看到所有内容,并且可以通过这种方式来使用functools的内部。

,

我自己做的。

def new_lru_cache(f):
    g = None
    def inner(*args,**kwargs):
        if cache:
            nonlocal g
            if g is None:
                g = lru_cache(f)
            return g(*args,**kwargs)
        else:
            return f(*args,**kwargs)
    return inner