[Python-ideas] Using functools.lru_cache only on some arguments of a function

Michael Selik mike at selik.org
Mon Dec 7 12:48:10 EST 2015


On Mon, Dec 7, 2015 at 8:31 AM Serhiy Storchaka <storchaka at gmail.com> wrote:

> On 07.12.15 02:41, Michael Selik wrote:
> > On Sat, Dec 5, 2015 at 6:11 PM Serhiy Storchaka
> > <storchaka at gmail.com
> > <mailto:storchaka at gmail.com>> wrote:
> >
> >     On 04.12.15 23:44, Bill Winslow wrote:
> >      > def deterministic_recursive_calculation(input,
> partial_state=None):
> >      >      condition = do_some_calculations(input)
> >      >      if condition:
> >      >          return deterministic_recursive_calculation(reduced_input,
> >      > some_state)
> >      >
> >      > I want to memoize this function for obvious reasons, but I need
> the
> >      > lru_cache to ignore the partial_state argument, for its value
> >     does not
> >      > affect the output, only the computation expense.
> >
> >     Memoize a closure.
> >
> >     def deterministic_calculation(input):
> >           some_state = ...
> >           @lru_cache()
> >           def recursive_calculation(input):
> >               nonlocal some_state
> >               ...
> >               return recursive_calculation(reduced_input)
> >           return recursive_calculation(input)
> >
> >
> > This would provide the dynamic programming aspect for the recursion, but
> > not cache across successive calls to the outer function. It does look
> > cleaner than the OO version.
>
> Decorate the outer function too.
>

Wouldn't that put us back where we started -- the cache is inappropriately
keying on the state/shortcut?

    @lru_cache()
    def recursive(*args, shortcut=False):
        @lru_cache()
        def inner(*args):
            if shortcut: return 'took a shortcut'
            print('infinite recursion is fun!')
            return inner(*args)
        return inner(n)

Creating a separate wrapper would do it, so that the recursive function
isn't re-created each time.

    @lru_cache()
    def recursive(*args):
        if recursive.shortcut: return 'took a shortcut'
        print('infinite recursion is fun!')
        return recursive(*args)
    recursive.shortcut = False

    def wrapper(*args, shortcut=False):
        recursive.shortcut = shortcut
        return recursive(*args)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151207/128847fd/attachment.html>


More information about the Python-ideas mailing list