Skip to content
Advertisement

Lazy class attribute initialization

I have a class that takes only one input argument. This value will then be used to compute a number of attributes (only one in the following example). What is a pythonic way if I wanted to take the computation place only if I call the attribute. In addition, the result should be cached and attr2 must not be set from outside the 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)

Advertisement

Answer

Make attr2 a property, not an instance attribute.

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 is a private instance attribute that both indicates whether the value has been computed yet, and saves the computed value for future access.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement