On Sun, Apr 26, 2020 at 05:31:22PM +0100, Tom Forbes wrote:
What if the functions requires arguments? How to cache calls with different arguments? What if some arguments are not hashable?
Then I think lru_cache is perfectly suitable for that use case. `once()` would only be useful if you’re calling a function with no arguments and therefore return a constant value. I originally thought that an exception could be raised if `@once()` was used with a function that accepted arguments, but it might be better to instead simply ignore arguments instead?
It's better to start by enforcing the "no arguments" restriction and relaxing it later than the relax the restriction from the beginning and then be sorry about it. So raise if the decorated argument takes arguments. If we change our mind, it is easier to add support for arguments later. This may require special-handling of (class|static)methods, or possibly two versions, see `singledispatch` and `singledispatchmethod`. It might also help to see what other languages do, such as Eiffel.
Why ``functools``? Why not your own library or a package at PyPI. Like https://pypi.org/project/cachetools/ ?
Because `lru_cache` fits the use case almost perfectly, is available in the stdlib and is very, very fast. As such people are using it like they would use `once()` which to me feels like a good argument to either special case `lru_cache()` to account for this or explicitly add a complimentary `once()` method alongside `lru_cache`. Adding a complimentary method seems better.
`once` may even end up being a thin wrapper around `lru_cache`. The idea (for me) is to provide a more discoverable, self-descriptive name, with any performance benefit of a simplified implementation being a bonus. -- Steven