考虑以下几点:
@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,真正的计算不依赖于可变值
当前回答
免责声明:我是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))来装饰你的函数/属性/类/方法…)
其他回答
啊,只需要给这个找到一个正确的名字:“懒惰的属性评估”。
我也经常这样做;也许有一天我会在我的代码中使用这个配方。
Werkzeug有一个cached_property装饰器(docs, source)
class memorize(dict):
def __init__(self, func):
self.func = func
def __call__(self, *args):
return self[args]
def __missing__(self, key):
result = self[key] = self.func(*key)
return result
示例使用:
>>> @memorize
... def foo(a, b):
... return a * b
>>> foo(2, 4)
8
>>> foo
{(2, 4): 8}
>>> foo('hi', 3)
'hihihi'
>>> foo
{(2, 4): 8, ('hi', 3): 'hihihi'}
在Python Wiki中还有另一个备忘录装饰器的例子:
http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
这个例子有点聪明,因为如果参数是可变的,它不会缓存结果。(检查代码,它非常简单和有趣!)
fastcache,这是Python 3 functools.lru_cache的C实现。提供10-30倍于标准库的加速。”
和选择的答案一样,只是导入不同:
from fastcache import lru_cache
@lru_cache(maxsize=128, typed=False)
def f(a, b):
pass
此外,它安装在Anaconda中,不像functools需要安装。