[{"data":1,"prerenderedAt":62},["ShallowReactive",2],{"qa-\u002Fpython\u002Ffunctional\u002Ffunctools":3},{"page":4,"siblings":53,"blog":44},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":44,"seo":45,"seoDescription":46,"stem":47,"subtopic":48,"topic":49,"topicSlug":50,"updated":51,"__hash__":52},"qa\u002Fpython\u002Ffunctional\u002Ffunctools.md","Functools",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Python","python",{},true,1,"\u002Fpython\u002Ffunctional\u002Ffunctools",[23,27,31,35,39],{"id":24,"difficulty":14,"q":25,"a":26},"lru-cache","What does functools.lru_cache do?","**`functools.lru_cache`** is a decorator that **memoizes** a function — it stores\nresults keyed by the arguments and returns the cached value on repeat calls,\navoiding recomputation. `maxsize` caps how many results are kept, evicting the\n**least-recently-used** entries; `lru_cache(maxsize=None)` (or `functools.cache`\nin 3.9+) caches without limit.\n\n```python\nfrom functools import lru_cache\n\n@lru_cache(maxsize=None)\ndef fib(n):\n    return n if n \u003C 2 else fib(n - 1) + fib(n - 2)\n\nfib(50)                 # fast — each n computed once\nfib.cache_info()        # hits, misses, maxsize, currsize\nfib.cache_clear()       # reset the cache\n```\n\nArguments must be **hashable** (they're used as dict keys), and the function should\nbe **pure** — caching an impure function returns stale results. Rule of thumb: use\nit for expensive, deterministic calls with repeated inputs.\n",{"id":28,"difficulty":14,"q":29,"a":30},"partial","What is functools.partial used for?","**`functools.partial`** creates a new callable with some arguments of an existing\nfunction **pre-filled**. It's a clean way to specialize a general function without\nwriting a wrapper or a `lambda`.\n\n```python\nfrom functools import partial\n\ndef power(base, exp):\n    return base ** exp\n\nsquare = partial(power, exp=2)   # exp fixed to 2\ncube   = partial(power, exp=3)\n\nsquare(5)    # 25\ncube(2)      # 8\n```\n\nPartials are handy for callbacks, event handlers, and configuring functions passed\nto `map`\u002F`sorted`\u002FGUI bindings. Rule of thumb: reach for `partial` when you keep\ncalling the same function with one or two fixed arguments.\n",{"id":32,"difficulty":14,"q":33,"a":34},"wraps","Why do you use functools.wraps when writing a decorator?","A decorator replaces the original function with a wrapper, which **loses the\noriginal's metadata** — its `__name__`, `__doc__`, and signature now point at the\nwrapper. **`functools.wraps`** copies that metadata from the wrapped function onto\nthe wrapper, so introspection, debugging, and documentation still work.\n\n```python\nfrom functools import wraps\n\ndef log(fn):\n    @wraps(fn)                 # copy fn's metadata to wrapper\n    def wrapper(*args, **kwargs):\n        print(\"calling\", fn.__name__)\n        return fn(*args, **kwargs)\n    return wrapper\n\n@log\ndef greet(): \"say hi\"\ngreet.__name__   # 'greet'  (without @wraps it'd be 'wrapper')\n```\n\nWithout `@wraps`, tools like `help()`, tracebacks, and doc generators show the\nwrapper instead of the real function. Rule of thumb: always add `@wraps(fn)` to the\ninner function of any decorator.\n",{"id":36,"difficulty":14,"q":37,"a":38},"reduce","What does functools.reduce do?","**`functools.reduce`** repeatedly applies a two-argument function across an iterable,\n**folding** it down to a single accumulated value. It carries a running result,\ncombining it with each element in turn; an optional **initializer** seeds the\naccumulator (and makes it safe on empty iterables).\n\n```python\nfrom functools import reduce\n\nreduce(lambda acc, x: acc + x, [1, 2, 3, 4])      # 10\nreduce(lambda acc, x: acc * x, [1, 2, 3, 4], 1)   # 24, seeded with 1\n```\n\nFor common folds Python already has built-ins (`sum`, `max`, `min`, `any`, `all`)\nthat are clearer and faster — `reduce` shines for custom accumulation logic. Rule\nof thumb: prefer a built-in or an explicit loop unless the fold is genuinely\nbespoke, since `reduce` can hurt readability.\n",{"id":40,"difficulty":41,"q":42,"a":43},"cached-property-singledispatch","hard","What are cached_property and singledispatch?","**`functools.cached_property`** turns a method into a property whose result is\n**computed once and stored on the instance**, so later accesses are cheap. The\ncached value lives in the instance `__dict__` and is recomputed only if you delete\nit. **`functools.singledispatch`** creates a **generic function** that dispatches to\ndifferent implementations based on the **type of the first argument** — function\noverloading by type.\n\n```python\nfrom functools import cached_property, singledispatch\n\nclass Dataset:\n    @cached_property\n    def stats(self):           # expensive; runs once per instance\n        return expensive_scan(self.data)\n\n@singledispatch\ndef describe(x): return f\"value: {x}\"\n@describe.register\ndef _(x: list): return f\"list of {len(x)}\"\n@describe.register\ndef _(x: int): return f\"int {x}\"\n\ndescribe([1, 2])   # 'list of 2'\ndescribe(7)        # 'int 7'\n```\n\n`cached_property` trades memory for speed on costly, stable computations;\n`singledispatch` keeps type-specific behaviour in separate, registerable functions\ninstead of a big `if\u002Fisinstance` chain. Rule of thumb: cache derived values that\ndon't change, and dispatch when behaviour varies cleanly by argument type.\n",null,{"description":11},"Python interview questions on functools — lru_cache and cache, partial, wraps, reduce, cached_property, and singledispatch.","python\u002Ffunctional\u002Ffunctools","functools","Functional Programming","functional","2026-06-18","O3Gm_dZN9ODH7b85aBNZuE1Zy-RWDP_xQIzayQMjmcM",[54,55,58],{"subtopic":48,"path":21,"order":20},{"subtopic":56,"path":57,"order":12},"map, filter & reduce","\u002Fpython\u002Ffunctional\u002Fmap-filter-reduce",{"subtopic":59,"path":60,"order":61},"itertools","\u002Fpython\u002Ffunctional\u002Fitertools",3,1781808681102]