Hi,
I’m adding an invariant computed property to an “immutable” dataclass.
After reading the documentation of the @functools.cached_property
it’s not clear to me which approach is preferred for my case: @cached_property
or @property @cache
.
Hi,
I’m adding an invariant computed property to an “immutable” dataclass.
After reading the documentation of the @functools.cached_property
it’s not clear to me which approach is preferred for my case: @cached_property
or @property @cache
.
The documentation isn’t making a claim about what should be done, but what can be done. If using @property
(potentially with some other caching decorator), you cannot set the attribute (without a setter).
The reason the documentation needs to point this out is because otherwise users may assume that @cached_property
has the exact same semantics as @property
, which is not the case.
It sounds like you probably just want to use @cached_property
.
(Also for what it’s worth, I find the semantics of @cache
on methods is easy to get confused about, e.g. you end up with a class-wide cache instead of an instance-wide cache)
*reworded the question
The way I read the documentation: use @property @cached
unless you want the users of the class to mutate and reset the cache.
But how “similar” is similar? Are there any other implementation-detail side effects that are ommited from the current documentation, e.g. @cached_property
being somehow “faster”?
unless you want the users of the class to mutate and reset the cache
Python follows the philosophy of “consenting adults”. It’s possible for users to reset the cache with @property
+ @cache
as well. In both cases, users have to go out of their way to do it.
Yes, like I said, you’d probably end up with a class-level cache instead of an instance-level cache, which in my opinion is usually not what you want. cached_property is much faster, but you’d need to benchmark to know how much faster for your use case (e.g. does your class implement a custom __hash__
).
Indeed, that’s the case.
Another side effect mentioned in the FAQ (and the doc for @lru_cache
: @property @cache
will keep the instance alive.