问题描述
如何从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