我要缓存的功能类似于:
def a(x, time='last'):
除a(x,y)
以外,我对每个y=='last'
都具有确定性行为。因此,在调用a(x, 'last')
时,我想调用“真实的东西”和其他所有功能的lru_cached函数。
我想这可以通过我自己的装饰器来实现:
def my_lru_cache(func):
def function_wrapper(*args, **kwargs):
if kwargs is not None:
if 'time' in kwargs:
return func(*args, **kwargs)
else:
return what?!?
return function_wrapper
我完全错了吗?该怎么办?
答案 0 :(得分:3)
在lru_cache()
中包装函数,然后在顶部添加装饰器,并通过__wrapped__
属性访问原始的未缓存函数,或者更好的是,使用inspect.unwrap()
function剥离函数任意数量的装饰器:
from functools import wraps
from inspect import unwrap
def bypass_cache_last_time(func):
@wraps(func)
def function_wrapper(*args, **kwargs):
if not 'time' in kwargs or kwargs['time'] == 'last':
# Bypass any additional decorators and call function directly
return unwrap(func)(*args, **kwargs)
else:
return func(*args, **kwargs)
return function_wrapper
并将其用作
@bypass_cache_last_time
@lru_cache()
def some_function(x, time='last'):
# ...
functools.wraps()
装饰器通过重新设置包装器的能力,因为它在包装器上设置了__wrapped__
属性。
或者让您的装饰器自己应用lru_cache()
装饰器,并在装饰时保留原始功能的副本:
def my_lru_cache(func):
cached = lru_cache()(func)
@wraps(func)
def function_wrapper(*args, **kwargs):
if not 'time' in kwargs or kwargs['time'] == 'last':
# call the function directly
return func(*args, **kwargs)
else:
# use the lru_cache-wrapped version
return cached(*args, **kwargs)
return function_wrapper
将此用作
@my_lru_cache
def some_function(x, time='last'):
# ...
答案 1 :(得分:1)
您可以直接致电lru_cache()
,以使用func
获取lru_cache(<args>)(func)
的“包装”版本。然后,您可以从包装器中将其返回:
def my_lru_cache(func):
caching_func = lru_cache()(func)
def function_wrapper(*args, **kwargs):
if kwargs.get('time') == 'last':
return func(*args, **kwargs)
return caching_func(*args, **kwargs)
return function_wrapper