Hello,
After a great discussion in python-ideas[1][2] it was suggested that I
cross-post this proposal to python-dev to gather more comments from those who
don't follow python-ideas.
The proposal is to add a "call_once" decorator to the functools module that, as
the name suggests, calls a wrapped function once, caching the result and
returning it with subsequent invocations. The rationale behind this proposal is
that:
1. Developers are using "lru_cache" to achieve this right now, which is less
efficient than it could be
2. Special casing "lru_cache" to account for zero arity methods isn't trivial
and we shouldn't endorse lru_cache as a way of achieving "call_once" semantics
3. Implementing a thread-safe (or even non-thread safe) "call_once" method is
non-trivial
4. It complements the lru_cache and cached_property methods currently present
in functools.
The specifics of the method would be:
1. The wrapped method is guaranteed to only be called once when called for the
first time by concurrent threads
2. Only functions with no arguments can be wrapped, otherwise an exception is
thrown
3. There is a C implementation to keep speed parity with lru_cache
I've included a naive implementation below (that doesn't meet any of the
specifics listed above) to illustrate the general idea of the proposal:
```
def call_once(func):
sentinel = object() # in case the wrapped method returns None
obj = sentinel
@functools.wraps(func)
def inner():
nonlocal obj, sentinel
if obj is sentinel:
obj = func()
return obj
return inner
```
I'd welcome any feedback on this proposal, and if the response is favourable
I'd love to attempt to implement it.
1.
https://mail.python.org/archives/list/[email protected]/thread/5OR3LJO7LOL6SC4OOGKFIVNNH4KADBPG/#5OR3LJO7LOL6SC4OOGKFIVNNH4KADBPG
2.
https://discuss.python.org/t/reduce-the-overhead-of-functools-lru-cache-for-functions-with-no-parameters/3956
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/5CFUCM4W3Z36U3GZ6Q3XBLDEVZLNFS63/
Code of Conduct: http://python.org/psf/codeofconduct/