functools.cached_property computes an attribute once per instance and then returns the stored value. Build your own.
Implement a descriptor class cached_property(func):
func(instance), store the result in the instance's __dict__ under the attribute's name (learned via __set_name__) and return it. Because the descriptor is a non-data descriptor (it defines no __set__), later lookups find the instance attribute first and never call the descriptor again.Also implement invalidate(obj, name): drop the cached value so the next access recomputes it (doing nothing if it isn't cached).