AtomLearnAtomLearn
DashboardGoalsPathAchievementsReviewSign In
Python CoreNot Started

functools

partial, lru_cache, reduce, wraps — the functional toolkit

0%
Knowledge0%
Learn & Drill
Fluency0%
Drill & Speed
Retention0%
Mastery & Review
Confidence0%
All modes
Practice

Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.

Upgrade
Knowledge
Fluency
Retention

Knowledge 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)  # cached

partial 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

Continue