考虑以下几点:
@property
def name(self):
if not hasattr(self, '_name'):
# expensive calculation
self._name = 1 + 1
return self._name
我是新来的,但我认为缓存可以分解成一个装饰器。只是我没有找到一个这样的;)
PS,真正的计算不依赖于可变值
考虑以下几点:
@property
def name(self):
if not hasattr(self, '_name'):
# expensive calculation
self._name = 1 + 1
return self._name
我是新来的,但我认为缓存可以分解成一个装饰器。只是我没有找到一个这样的;)
PS,真正的计算不依赖于可变值
当前回答
除了Memoize示例,我还找到了以下python包:
cachepy;它允许设置ttl和\或缓存函数的调用次数;此外,还可以使用加密的基于文件的缓存… percache
其他回答
除了Memoize示例,我还找到了以下python包:
cachepy;它允许设置ttl和\或缓存函数的调用次数;此外,还可以使用加密的基于文件的缓存… percache
我实现了类似的东西,使用pickle进行持久化,使用sha1进行简短的几乎唯一的id。基本上,缓存对函数代码和参数的历史进行哈希,以获得sha1,然后查找名称为sha1的文件。如果它存在,则打开它并返回结果;如果没有,则调用该函数并保存结果(如果需要一定时间来处理,则可以选择只保存结果)。
也就是说,我发誓我找到了一个现有的模块,它做到了这一点,并发现自己在这里试图找到该模块……我能找到的最接近的是这个,看起来差不多:http://chase-seibert.github.io/blog/2011/11/23/pythondjango-disk-based-caching-decorator.html
我看到的唯一问题是,它不能很好地用于大输入,因为它散列str(arg),这不是唯一的大型数组。
如果有一个unique_hash()协议,让一个类返回其内容的安全散列,那就太好了。我基本上是手动实现我所关心的类型。
从Python 3.2开始,有一个内置的装饰器:
@functools。lru_cache(最大容量= 100,输入= False)
装饰器使用一个可记忆可调用对象来包装函数,该可调用对象最多保存maxsize最近的调用。当使用相同的参数周期性地调用昂贵的或I/O绑定的函数时,它可以节省时间。
用于计算斐波那契数的LRU缓存示例:
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
>>> print([fib(n) for n in range(16)])
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
>>> print(fib.cache_info())
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
如果你被Python 2困住了。X,这里是其他兼容的内存库列表:
functools32 | PyPI |源代码 repoze。lru | PyPI |源代码 pylru | PyPI |源代码 补丁。functools_lru_cache | PyPI |源代码
创建自己的装饰器并使用它
from django.core.cache import cache
import functools
def cache_returned_values(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
key = "choose a unique key here"
results = cache.get(key)
if not results:
results = func(*args, **kwargs)
cache.set(key, results)
return results
return wrapper
现在看函数
@cache_returned_values
def get_some_values(args):
return x
functools。缓存已经在Python 3.9 (docs)中发布:
from functools import cache
@cache
def factorial(n):
return n * factorial(n-1) if n else 1
在以前的Python版本中,早期的答案之一仍然是有效的解决方案:使用lru_cache作为普通缓存,没有限制和lru特性。(文档)
如果maxsize设置为None,将禁用LRU特性,并将缓存 可以不受束缚地成长。
这里有一个更漂亮的版本:
cache = lru_cache(maxsize=None)
@cache
def func(param1):
pass