Decorator to wrap a function with a memoizing callable that saves up to the
maxsize most recent calls. It can save time when an expensive or I/O bound
function is periodically called with the same arguments.
Since a dictionary is used to cache results, the positional and keyword
arguments to the function must be hashable.
If maxsize is set to None, the LRU feature is disabled and the cache can
grow without bound. The LRU feature performs best when maxsize is a
power-of-two.
If typed is set to true, function arguments of different types will be
cached separately. For example, f(3) and f(3.0) will be treated
as distinct calls with distinct results.
To help measure the effectiveness of the cache and tune the maxsize
parameter, the wrapped function is instrumented with a cache_info()
function that returns a named tuple showing hits, misses,
maxsize and currsize. In a multi-threaded environment, the hits
and misses are approximate.
The decorator also provides a cache_clear() function for clearing or
invalidating the cache.
The original underlying function is accessible through the
__wrapped__ attribute. This is useful for introspection, for
bypassing the cache, or for rewrapping the function with a different cache.
An LRU (least recently used) cache works
best when the most recent calls are the best predictors of upcoming calls (for
example, the most popular articles on a news server tend to change each day).
The cache’s size limit assures that the cache does not grow without bound on
long-running processes such as web servers.
Example of an LRU cache for static web content:
@lru_cache(maxsize=32)
def get_pep(num):
'Retrieve text of a Python Enhancement Proposal'
resource = 'http://www.python.org/dev/peps/pep-%04d/' % num
try:
with urllib.request.urlopen(resource) as s:
return s.read()
except urllib.error.HTTPError:
return 'Not Found'
>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
... pep = get_pep(n)
... print(n, len(pep))
>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
Example of efficiently computing
Fibonacci numbers
using a cache to implement a
dynamic programming
technique:
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
Changed in version 3.3: Added the typed option.