延迟 class 属性初始化

Lazy class attribute initialization

我有一个只接受一个输入参数的 class。然后该值将用于计算多个属性(以下示例中只有一个)。如果我只想在调用属性时进行计算,那么什么是 pythonic 方式。此外,结果应该被缓存并且 attr2 不能从 class.

之外设置
class LazyInit:
    def __init__(self, val):
        self.attr1 = val
        self.attr2 = self.compute_attr2()

    def compute_attr2(self):
        return self.attr1 * 2  # potentially costly computation


if __name__ == "__main__":
    obj = LazyInit(10)

    # actual computation should take place when calling the attribute
    print(obj.attr2)

使 attr2 成为 属性,而不是实例属性。

class LazyInit:
    def __init__(self, val):
        self.attr1 = val
        self._attr2 = None

    @property
    def attr2(self):
        if self._attr2 is None:
            self._attr2 = self.compute_attr2()
        return self._attr2

_attr2是一个私有实例属性,既表示该值是否已经被计算出来,又保存计算出的值以供将来访问。

正如提示 ,只需使用 @cached_property 装饰器。

from functools import cached_property

class LazyInit():
    ...
    @cached_property
    def attr2(self):
        return <perform expensive computation>

Olvin Roght correctly 此解决方案不会像 @property 那样使 attr2 只读。如果这对你很重要,另一种可能性是写:

    ...
    @property
    def attr2(self):
        return self.__internal_attr2()

    @functools.cached
    def __internal_attr2(self):
        return <perform expensive calculation>

无论如何,Python 提供了库来帮助您确保一个值只计算一次。使用它们比尝试编写自己的更好。