Backports functools.lru_cache
This library provides a backport of the `functools.lru_cache` decorator, originally introduced in Python 3.2, primarily for use in older Python environments (e.g., Python 2.7, 3.2-3.5). For Python versions 3.8 and newer, it acts as a no-op, internally importing the built-in `functools.lru_cache` for compatibility. The current version is 2.0.0, released in December 2023, with updates occurring on an as-needed basis rather than a fixed cadence.
Warnings
- gotcha This library is primarily intended for Python versions older than 3.8 (or more generally, older than 3.2, where `lru_cache` was introduced). On Python 3.8+ environments, installing and using this package is largely a no-op, as it will simply re-export the built-in `functools.lru_cache`.
- gotcha The `lru_cache` (both built-in and backported) stores references to the return values. If a mutable object (like a list or dictionary) is returned and subsequently modified, the cached value will also reflect these changes, potentially leading to incorrect behavior upon future cache hits.
- gotcha When applying `@lru_cache` to methods of dataclasses (especially frozen ones), the cache key might be based on the instance's hash. If multiple instances hash to the same value (common with frozen dataclasses that equate/hash based on field values), the cache can become shared across instances, causing method calls on different objects to return the same cached result.
Install
-
pip install backports-functools-lru-cache
Imports
- lru_cache
try: from functools import lru_cache except ImportError: from backports.functools_lru_cache import lru_cache
Quickstart
import time
try:
from functools import lru_cache
except ImportError:
from backports.functools_lru_cache import lru_cache
@lru_cache(maxsize=128)
def expensive_computation(n):
"""Simulates an expensive computation."""
time.sleep(0.1) # Simulate work
return n * n
print("First call:")
start = time.perf_counter()
result1 = expensive_computation(5)
end = time.perf_counter()
print(f"Result: {result1}, Time taken: {end - start:.4f}s")
print("\nSecond call (should be cached):")
start = time.perf_counter()
result2 = expensive_computation(5)
end = time.perf_counter()
print(f"Result: {result2}, Time taken: {end - start:.4f}s")
print(f"\nCache Info: {expensive_computation.cache_info()}")