Home > Mobile >  Does python's functools lru_cache caches function parameters alongside the result?
Does python's functools lru_cache caches function parameters alongside the result?

Time:08-24

For the following program:

from functools import lru_cache


@lru_cache(maxsize=256)
def task_a(a, b):
    print(f'Multiplying {a} and {b}')
    return a*b


print(task_a(2, 3))
print(task_a(2, 3))

print(task_a(2, 4))
print(task_a(2, 4))

print(task_a(2, 5))
print(task_a(2, 5))

I got the following output:

Multiplying 2 and 3
6
6
Multiplying 2 and 4
8
8
Multiplying 2 and 5
10
10

My question is, if this decorator is applied on the function, does it make use of function parameters or does it caches the function parameters along with the result?

If no, then how does it know not to execute the function when same parameters are passed?

CodePudding user response:

It does cache the parameters. In fact, the parameters must be hashable for the cache to work:

>>> from functools import lru_cache
>>> @lru_cache
... def test(l):
...  pass
...
>>> test([])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

For more info, you can take a look at the source code.

CodePudding user response:

The arguments and the return value of the wrapped function are cached in a dictionary, and if those same arguments are used again, the return value from the previous call to the wrapped function is returned, but the function is not called multiple times.

The basic logic is like this:

  • Make a tuple out of the cached arguments (in your example, this means (2, 3))
  • If the tuple key exists in the cache dictionary, return the cached value, without calling the wrapped function
  • If the tuple key did not exist, call the wrapped function
  • Save the results of the wrapped function in the cache dictionary (using the argument tuple as the key)
  • Return the wrapped function results

In pseudo-code, it's like this:

key = make_key(args)
if key in cache:
    return cache[key]
result = func(args)
cache[key] = result
return result
  • Related