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.