考虑以下几点:

@property
def name(self):

    if not hasattr(self, '_name'):

        # expensive calculation
        self._name = 1 + 1

    return self._name

我是新来的,但我认为缓存可以分解成一个装饰器。只是我没有找到一个这样的;)

PS,真正的计算不依赖于可变值


当前回答

啊,只需要给这个找到一个正确的名字:“懒惰的属性评估”。

我也经常这样做;也许有一天我会在我的代码中使用这个配方。

其他回答

如果你正在使用Django框架,它有这样一个属性来缓存API的视图或响应 使用@cache_page(time),也可以有其他选项。

例子:

@cache_page(60 * 15, cache="special_cache")
def my_view(request):
    ...

更多细节可以在这里找到。

创建自己的装饰器并使用它

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

Werkzeug有一个cached_property装饰器(docs, source)

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

除了Memoize示例,我还找到了以下python包:

cachepy;它允许设置ttl和\或缓存函数的调用次数;此外,还可以使用加密的基于文件的缓存… percache