Memoization
Memoization is a powerful caching library for Python, providing decorators for function memoization with features like Time-To-Live (TTL) expiration, multiple caching algorithms (LRU, LFU, FIFO), and extensibility. It aims to solve some limitations of the standard library's `functools.lru_cache`, such as handling unhashable arguments. The library is actively developed, with its latest release being v0.4.0.
Warnings
- breaking Python 2 support was entirely removed in version `0.2.2`. Additionally, support for Python 3.2 and 3.3 was dropped in `v0.1.4`. Users on these older Python versions must upgrade their Python environment to use `memoization` versions >= `0.2.2` (for Python 2) or >= `0.1.4` (for Python 3.2/3.3).
- breaking The API for on-demand partial cache clearing underwent significant changes. This functionality was initially present, then explicitly dropped in `v0.1.4`, and later reintroduced with new APIs in `v0.4.0`. Code relying on specific partial cache clearing methods in versions between `v0.1.4` and `v0.4.0` would have failed, and existing code for clearing would need updates for `v0.4.0`.
- gotcha When using custom `key_maker` functions (introduced in `v0.3.1`), ensure they produce unique, hashable, and efficiently computable keys. A bug in versions prior to `v0.4.0` (`#8`) incorrectly required the key maker's signature to exactly match the cached function's signature. This strict requirement was relaxed in `v0.4.0`.
- gotcha For unhashable arguments (e.g., `list`, `dict`), `memoization` defaults to using `str()` to generate cache keys. While this feature allows caching functions with unhashable inputs (unlike `functools.lru_cache`), it can lead to unexpected cache behavior if the `str()` representation of mutable objects does not uniquely reflect their logical state or if different objects happen to have the same string representation. For complex or mutable unhashable arguments, a custom `key_maker` is often recommended.
- gotcha Thread safety was introduced in `v0.1.4`. Using `memoization` in multi-threaded applications with versions prior to `v0.1.4` could lead to race conditions, inconsistent cache states, or incorrect results due to concurrent access to the cache without proper locking. While `memoization` versions `v0.1.4` and later generally handle thread safety, be mindful of the performance implications and ensure it's enabled if required (`thread_safe=True` parameter).
Install
-
pip install memoization
Imports
- cached
from memoization import cached
Quickstart
import time
from memoization import cached
@cached(ttl=2) # Cache results for 2 seconds
def expensive_calculation(a, b):
print(f"Calculating {a} + {b}...")
time.sleep(1) # Simulate a slow operation
return a + b
print(expensive_calculation(1, 2)) # First call, calculates
print(expensive_calculation(1, 2)) # Second call, uses cache
time.sleep(3) # Wait for cache to expire
print(expensive_calculation(1, 2)) # Cache expired, recalculates
@cached(max_size=2, algorithm='lru')
def lru_example(x):
print(f"Calculating for {x}...")
return x * x
lru_example(1)
lru_example(2)
lru_example(3) # 1 will be evicted
lru_example(1) # Re-calculates for 1, 2 is evicted