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/python-id...@python.org/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 -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/5CFUCM4W3Z36U3GZ6Q3XBLDEVZLNFS63/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to