如何在Python的@functools.lru_cache中使用cache_clear()函数

106

文档中指出:

装饰器还提供了一个cache_clear()函数,用于清除或使缓存失效。

文档中没有提供关于如何使用cache_clear()的示例或指导。

我有两个问题:

  • 如何从另一个函数运行cache_clear()
  • 如果在被缓存的函数内有一个有条件的cache_clear()调用,它会执行吗?
3个回答

184

除了缓存,lru_cache 装饰器还会向被装饰的函数添加两个新函数 - cache_infocache_clear。下面是一个简单的例子,应该能够说明它们的工作原理:

>>> @lru_cache(5)
... def foo():
...     print('Executing foo...')
... 
>>> foo()
Executing foo...
>>> foo()
>>> foo.cache_info()
CacheInfo(hits=1, misses=1, maxsize=5, currsize=1)
>>> foo.cache_clear()
>>> foo()
Executing foo...

回答你的问题:

如果我在被缓存的函数中有一个有条件的cache_clear()调用,它会执行吗?

如果结果还没有被缓存,函数将会执行,并根据您的条件执行cache_clear。不过我不建议使用这种解决方案——最好的实践是在缓存对象之外进行失效处理,否则会在最坏的情况下导致根本没有失效,而在最好的情况下会导致难以阅读的代码。

如何从另一个函数运行cache_clear()?

只需导入缓存函数并在其上调用cache_clear

from x import foo

def bar():
    foo.cache_clear()

21

如果你尝试过期缓存的方法是一个属性:

class Foo:
    @property
    @lru_cache()
    def bar(self):
       return 42

然后你可以通过以下方式清除缓存:

Foo.bar.fget.cache_clear()

参考这个答案:https://dev59.com/CLLma4cB1Zd3GeqPjf_5#55497384


0
如果该方法被自定义函数装饰,例如:
Class myclass
    @dec1
    @dec2
    ...
    @decX
    @lru_cache()
    def myfunc()    

还可以通过访问__dict__,然后在其中访问__wrapped__键来访问lru_cache包装器,如有需要,可以多次执行此操作:

myclass.myfunc.__dict__["__wrapped__"].__dict__["__wrapped__"].....__dict__["__wrapped__"]cache_clear()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接