functools Interview Questions & Answers
5 questions Updated 2026-06-18
Python interview questions on functools — lru_cache and cache, partial, wraps, reduce, cached_property, and singledispatch.
functools.lru_cache is a decorator that memoizes a function — it stores
results keyed by the arguments and returns the cached value on repeat calls,
avoiding recomputation. maxsize caps how many results are kept, evicting the
least-recently-used entries; lru_cache(maxsize=None) (or functools.cache
in 3.9+) caches without limit.
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
return n if n < 2 else fib(n - 1) + fib(n - 2)
fib(50) # fast — each n computed once
fib.cache_info() # hits, misses, maxsize, currsize
fib.cache_clear() # reset the cache
Arguments must be hashable (they're used as dict keys), and the function should be pure — caching an impure function returns stale results. Rule of thumb: use it for expensive, deterministic calls with repeated inputs.
functools.partial creates a new callable with some arguments of an existing
function pre-filled. It's a clean way to specialize a general function without
writing a wrapper or a lambda.
from functools import partial
def power(base, exp):
return base ** exp
square = partial(power, exp=2) # exp fixed to 2
cube = partial(power, exp=3)
square(5) # 25
cube(2) # 8
Partials are handy for callbacks, event handlers, and configuring functions passed
to map/sorted/GUI bindings. Rule of thumb: reach for partial when you keep
calling the same function with one or two fixed arguments.
A decorator replaces the original function with a wrapper, which loses the
original's metadata — its __name__, __doc__, and signature now point at the
wrapper. functools.wraps copies that metadata from the wrapped function onto
the wrapper, so introspection, debugging, and documentation still work.
from functools import wraps
def log(fn):
@wraps(fn) # copy fn's metadata to wrapper
def wrapper(*args, **kwargs):
print("calling", fn.__name__)
return fn(*args, **kwargs)
return wrapper
@log
def greet(): "say hi"
greet.__name__ # 'greet' (without @wraps it'd be 'wrapper')
Without @wraps, tools like help(), tracebacks, and doc generators show the
wrapper instead of the real function. Rule of thumb: always add @wraps(fn) to the
inner function of any decorator.
functools.reduce repeatedly applies a two-argument function across an iterable,
folding it down to a single accumulated value. It carries a running result,
combining it with each element in turn; an optional initializer seeds the
accumulator (and makes it safe on empty iterables).
from functools import reduce
reduce(lambda acc, x: acc + x, [1, 2, 3, 4]) # 10
reduce(lambda acc, x: acc * x, [1, 2, 3, 4], 1) # 24, seeded with 1
For common folds Python already has built-ins (sum, max, min, any, all)
that are clearer and faster — reduce shines for custom accumulation logic. Rule
of thumb: prefer a built-in or an explicit loop unless the fold is genuinely
bespoke, since reduce can hurt readability.
functools.cached_property turns a method into a property whose result is
computed once and stored on the instance, so later accesses are cheap. The
cached value lives in the instance __dict__ and is recomputed only if you delete
it. functools.singledispatch creates a generic function that dispatches to
different implementations based on the type of the first argument — function
overloading by type.
from functools import cached_property, singledispatch
class Dataset:
@cached_property
def stats(self): # expensive; runs once per instance
return expensive_scan(self.data)
@singledispatch
def describe(x): return f"value: {x}"
@describe.register
def _(x: list): return f"list of {len(x)}"
@describe.register
def _(x: int): return f"int {x}"
describe([1, 2]) # 'list of 2'
describe(7) # 'int 7'
cached_property trades memory for speed on costly, stable computations;
singledispatch keeps type-specific behaviour in separate, registerable functions
instead of a big if/isinstance chain. Rule of thumb: cache derived values that
don't change, and dispatch when behaviour varies cleanly by argument type.
Practice tests are coming soon
Get notified when interactive mock interviews and quizzes launch.