Implement a memoization decorator in Python
py-mid-002
Your answer
Answer as you would in a real interview — explain your thinking, not just the conclusion.
Model answer
A memoization decorator wraps a function and caches results keyed by the call arguments. I use functools.wraps to preserve the original function's name and docstring, and a plain dict for the cache. For production, functools.lru_cache(maxsize=...) is always preferable: it is thread-safe (uses a lock internally), supports LRU eviction so the cache does not grow unboundedly, and handles typed caching. A custom implementation is useful to understand the pattern or when you need custom cache invalidation, TTL, or distributed caching.
Code example
import functools
def memoize(func):
cache = {}
@functools.wraps(func)
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fib(n):
return n if n < 2 else fib(n - 1) + fib(n - 2)
print(fib(30)) # 832040, fast due to caching
# Standard library alternative (preferred in production)
from functools import lru_cache
@lru_cache(maxsize=256)
def fib_std(n):
return n if n < 2 else fib_std(n - 1) + fib_std(n - 2)
Follow-up
How would you make your memoize decorator thread-safe? What would change if the wrapped function is a coroutine (async def)?