考虑以下几点:
@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,真正的计算不依赖于可变值
当前回答
Werkzeug有一个cached_property装饰器(docs, source)
其他回答
啊,只需要给这个找到一个正确的名字:“懒惰的属性评估”。
我也经常这样做;也许有一天我会在我的代码中使用这个配方。
Werkzeug有一个cached_property装饰器(docs, source)
尝试joblib https://joblib.readthedocs.io/en/latest/memory.html
from joblib import Memory
memory = Memory(cachedir=cachedir, verbose=0)
@memory.cache
def f(x):
print('Running f(%s)' % x)
return x
免责声明:我是kids.cache的作者。
你应该检查孩子。Cache,它提供了一个在python 2和python 3上工作的@cache装饰器。没有依赖关系,大约100行代码。它的使用非常简单,例如,在你的代码中,你可以这样使用:
pip install kids.cache
Then
from kids.cache import cache
...
class MyClass(object):
...
@cache # <-- That's all you need to do
@property
def name(self):
return 1 + 1 # supposedly expensive calculation
或者你可以把@cache装饰器放在@属性之后(同样的结果)。
在属性上使用缓存被称为惰性求值。缓存可以做更多的事情(它适用于带有任何参数、属性、任何类型的方法,甚至是类的函数……)对于高级用户,儿童。cache支持cachetools,它为python 2和python 3提供了漂亮的缓存存储(LRU, LFU, TTL, RR缓存)。
重要提示:孩子的默认缓存存储。缓存是一个标准字典,不建议长时间运行具有不同查询的程序,因为它会导致缓存存储不断增长。对于这种用法,你可以使用插件其他缓存存储使用例如(@cache(use=cachetools.LRUCache(maxsize=2))来装饰你的函数/属性/类/方法…)
创建自己的装饰器并使用它
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