functools
partial, lru_cache, reduce, wraps — the functional toolkit
Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.
UpgradeKnowledge Debt detected
You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.
Explanation
functools is the standard library module for higher-order functions. Four tools you'll use regularly:
lru_cache — memoize a function's results: ``python from functools import lru_cache @lru_cache(maxsize=128) def fibonacci(n): if n < 2: return n return fibonacci(n - 1) + fibonacci(n - 2) fibonacci(100) # fast — each subproblem computed once fibonacci.cache_info() # CacheInfo(hits=98, misses=101, ...)
partial — fix some arguments, create a specialized function: ``python from functools import partial def power(base, exp): return base ** exp square = partial(power, exp=2) cube = partial(power, exp=3) square(5) # 25 cube(3) # 27
reduce — fold a sequence to a single value: ``python from functools import reduce product = reduce(lambda acc, x: acc * x, [1, 2, 3, 4, 5]) # 120 # acc starts at first element; each step: acc = f(acc, next)
wraps — preserve metadata when writing decorators: ``python from functools import wraps def logged(func): @wraps(func) # copies __name__, __doc__ etc from func def wrapper(*args, **kwargs): print(f"Calling {func.__name__}") return func(*args, **kwargs) return wrapper @logged def add(a, b): """Add two numbers.""" return a + b add.__name__ # 'add' (not 'wrapper') add.__doc__ # 'Add two numbers.'
Examples
lru_cache for expensive API calls
lru_cache eliminates redundant I/O — essential for performance-sensitive code
from functools import lru_cache
import httpx
@lru_cache(maxsize=256)
def get_user(user_id: int) -> dict:
response = httpx.get(f"https://api.example.com/users/{user_id}")
return response.json()
# Second call with same id hits cache — no HTTP request
user = get_user(42)
user = get_user(42) # cachedpartial for configuring callbacks
partial removes repetition when the same argument is always the same
from functools import partial
def send_notification(user_id: int, channel: str, message: str) -> None:
print(f"→ {channel} to user {user_id}: {message}")
# Create pre-configured notification senders
email_notify = partial(send_notification, channel="email")
sms_notify = partial(send_notification, channel="sms")
email_notify(user_id=42, message="Your order shipped!")
sms_notify(user_id=7, message="OTP: 123456")How well did you understand this?
Next in Python Core
async / await