只计算 属性 一次并多次使用结果(不同的方法)

Calculate property only once and use the result several times (different approaches)

我尝试多次使用 class 方法的结果,但没有进行获得结果所需的繁重计算。

我看到以下选项。你认为哪一个是正确的,或者更pythonic?

各自的优缺点是什么?

Try/Except接近

class Test:
    def __init__(self, *args):
        # do stuff

    @property
    def new_method(self):
        try:
            return self._new_property
        except AttributeError:
            # do some heavy calculations
            return self._new_property

lru_cache接近

from functools import lru_cache

class Test:
    def __init__(self, *args):
        # do stuff

    @property
    @lru_cache()
    def new_method(self):
        # do some heavy calculations
        return self._new_property

Django 的 cache_property 方法

from django.utils.functional import cached_property

class Test:
    def __init__(self, *args):
        # do stuff

    @cached_property
    def new_method(self):
        # do some heavy calculations
        return self._new_property
  1. Try/except 简单易读,但总有一天你会想要缓存另一个 属性,对吧?所以有一天你会写你自己的缓存 属性 可能。

  2. lru_cache 使用标准库是个好主意,但是因为你不需要 lru 缓存,这可能是一个开销.

  3. Django 的 cache_property 完全按照您的意愿工作,而且非常简单。它在 werkzeug 中有类似的东西(所以 Flask 用户也很熟悉它),很容易找到源代码,所以它可能是你不错的选择。

Python 3.8 更新:您现在可以使用 functools.cached_property

from functools import cached_property

class Test:
    def __init__(self, *args):
        # do stuff

    @cached_property
    def new_method(self):
        # do some heavy calculations
        return self._new_property