从内部函数禁用`functools.lru_cache`
Posted
技术标签:
【中文标题】从内部函数禁用`functools.lru_cache`【英文标题】:disable `functools.lru_cache` from inside function 【发布时间】:2019-10-25 21:55:11 【问题描述】:我想要一个可以使用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)
有没有更简单的方法来做到这一点?
【问题讨论】:
你不能在函数的内部处理它——如果它是缓存命中,函数甚至不会被调用。 所有你可以在这里正确地发明 - 只是一个工厂函数,它将返回缓存或未缓存的函数对象(取决于参数),而不是函数结果 RomanPerekhest 为什么我要返回函数对象而不是函数结果? @TheStrangeQuark,生成对象的场景有很多种。没有人强迫您扩展“家庭”代码,这取决于您 【参考方案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
【讨论】:
【参考方案2】:为了检查,你可以使用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)
【讨论】:
以上是关于从内部函数禁用`functools.lru_cache`的主要内容,如果未能解决你的问题,请参考以下文章
CSS3 Snow Fall Animation 禁用内部链接
因bug禁用内部IP导致链路不通,阿里云大面积瘫痪!Intel处理器又曝漏洞;Tomcat 9.0.10发布
如何从Objective-C中的异步内部函数内部返回外部函数