How to Invalidate Cache When Arguments Change in Python
A memoization decorator that caches function results keyed by arguments, automatically invalidating when inputs change.
Python code
24 linesfrom functools import wraps
def memoize(func):
cache = {}
@wraps(func)
def wrapper(*args, **kwargs):
key = (args, tuple(sorted(kwargs.items())))
if key not in cache:
cache[key] = func(*args, **kwargs)
return cache[key]
return wrapper
@memoize
def expensive_calculation(x, y):
print(f"Calculating for ({x}, {y})...")
return x * y + x + y
if __name__ == "__main__":
print(expensive_calculation(2, 3)) # Calculates
print(expensive_calculation(2, 3)) # Cached
print(expensive_calculation(3, 2)) # New args, calculates
print(expensive_calculation(2, 3)) # Cached again
Output
Calculating for (2, 3)...
11
11
Calculating for (3, 2)...
17
11
How it works
The @wraps decorator preserves the original function's metadata (name, docstring) so debugging stays clean. The cache key is built from args and sorted kwargs.items(), which ensures identical calls with different argument orders hit the same cache entry. When arguments change, the key differs, causing a recomputation — this is the automatic invalidation mechanism. The cache persists for the lifetime of the wrapped function, making it ideal for expensive, pure computations.
Common mistakes
- Using mutable objects as arguments (like lists) — they can't be hashed as cache keys
- Forgetting to sort kwargs items, causing redundant cache misses for swapped keyword arguments
- Not using @wraps, losing the original function's name and docstring
Variations
- Use `functools.lru_cache(maxsize=None)` for a built-in, thread-safe memoization decorator
- Add a TTL (time-to-live) parameter to expire cache entries after a set duration
Real-world use cases
- Caching database query results in a dashboard API to avoid repeated expensive lookups.
- Memoizing recursive Fibonacci or combinatorial functions in financial risk simulations.
- Storing parsed configurations in a microservice so repeated reads don't hit disk or network.
Sponsored
More from Functions & basics
- Add Type Hints to Function Parameters and Return in Python easy
- Benchmark list append vs comprehension in Python easy
- Build a Context Manager in Python with contextlib.contextmanager easy
- Build a Progress Callback Function for Loops in Python easy
- Cache expensive function with lru_cache in Python easy
- Calculate Time Difference Across Time Zones in Python easy
Keep learning
Related tutorials and quizzes for this topic.