The code below shows the pattern I use to manage properties in my classes when I have the following requirements:
- Some properties are slow to calculate and are rarely used, so I want them to be lazy
- Some methods change the value of a property
The properties are defined the first time they are requested and are deleted when the methods are executed. Calculating the length in the
Line class shown in the example is fairly fast, but calculating the
Length of a shape made of many
Lines would be slow and must be avoided unless required. The full code include many more properties and the list in
_reset_attributes([...]) can have dozens of items.
Is this the correct/pythonic/fast way of managing properties?
class Line: @property def angle(self): try: return self._angle except AttributeError: self._angle = math.atan2(self.end.y - self.start.y, self.end.x - self.start.x) return self._angle @property def length(self): try: return self._length except AttributeError: self._length = math.sqrt((self.end.x - self.start.x) ** 2 + (self.end.y - self.start.y) ** 2) return self._length def rotate(self, pivot_point, angle): self.start.rotate(pivot_point, angle) self.end.rotate(pivot_point, angle) self._reset_attributes(['_angle']) def scale(self, pivot_point, factor): self.start.scale(pivot_point, factor) self.end.scale(pivot_point, factor) self._reset_attributes(['_length']) def _reset_attributes(self, attributes): for attribute in attributes: try: delattr(self, attribute) except: pass