On 4/30/20 4:47 PM, raymond.hettin...@gmail.com wrote:
> Would either of the existing solutions work for you?
>
> class X:
>     def __init__(self, name):
>         self.name = name
>
>     @cached_property
>     def title(self):
>       print("compute title once")
>       return self.name.title()
>
>     @property
>     @lru_cache
>     def upper(self):
>       print("compute uppper once")
>       return self.name.upper()

The second one seems a bit dangerous in that it will erroneously keep
objects alive until they are either ejected from the cache or until the
class itself is collected (plus only 128 objects would be in the cache
at one time): https://bugs.python.org/issue19859

> Thanks for the concrete example.  AFAICT, it doesn't require (and probably 
> shouldn't have) a lock to be held for the duration of the call.  Would it be 
> fair to say the 100% of your needs would be met if we just added this to the 
> functools module?
>
>       call_once = lru_cache(maxsize=None)
I am -0 on adding `call_once = lru_cache(maxsize=None)` here. I feel
like it could be misleading in that people might think that it ensures
that the function is called exactly once (it reminds me of the FnOnce
<https://doc.rust-lang.org/std/ops/trait.FnOnce.html> trait in Rust),
and all it buys us is a nice way to advertise "here's a use case for
lru_cache".

That said, in any of the times I've had one of these "call exactly one
time" situations, the biggest constraint I've had is that I always
wanted the return value to be the same object so that `f(x) is f(x)`,
but I've never had a situation where it was /required/ that the function
be called exactly once, so I rarely if ever have bothered to get that
property.

I suppose I could imagine a situation where calling the function mutates
or consumes an object as part of the call, like:

class LazyList:
    def __init__(self, some_iterator):
        self._iter = some_iterator
        self._list = None

    @call_once
    def as_list(self):
        self._list = list(self._iter)
        return self._list

But I think it's just speculation to imagine anyone needs that or would
find it useful, so I'm in favor of waiting for someone to chime in with
a concrete use case where this property would be valuable.

Best,
Paul

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
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/BXOKFCVUNFJZBLMOMUYNLH4K4HFYBSYX/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to