Using a cached property on a named tuple
from typing import NamedTuple
from functools import cached_property
class Rectangle(NamedTuple):
x: int
y: int
@cached_property
def area(self):
return self.x * self.y
I thought this class definition would complain something about the __slots__
on Rectangle, but apparently the class definition is valid. It doesn't fail until too late, if/when the getter is actually accessed:
>>> rect = Rectangle(2, 3)
>>> rect.area
...
TypeError: Cannot use cached_property instance without calling __set_name__ on it.
>>> Rectangle.
Well, that's weird, but okay..
>>> Rectangle.area.__set_name__(Rectangle, "area")
>>> rect.area
...
TypeError: No '__dict__' attribute on 'Rectangle' instance to cache 'area' property.
Is there a better recipe for cached properties on named tuples? Requirements:
- It should not appear to be a real field (
x, y, area = rect
should not be possible) - It should be lazy (not eagerly computed) and cached (not recomputed every time accessed)
- Wherever the storage is should not leak memory (it should be deleted when the tuple instance itself is deleted)
Comments
Post a Comment