Meaning
functools.wraps copies essential attributes (__name__, __module__, __qualname__, __doc__, __annotations__) from the original function to the wrapper function. Without it, a decorator would hide the original function's identity, breaking introspection tools like help() and debugging. You reach for this pattern when you need to add behavior via a decorator while preserving the wrapped function's metadata.
Primary Function
Decorators
Communicative Purpose
Preserves function metadata and introspection capabilities when applying decorators.
Pattern
functools.wraps(original_func)(lambda *args, **kwargs: original_func(*args, **kwargs))
Core Structure
functools.wraps(...)(lambda ...: ...(...))
Função primária
Decorators
Propósito comunicativo
Preserves function metadata and introspection capabilities when applying decorators.
Situações de gatilho
Python: adding logging to functions without losing their __name__; Python: timing function execution while preserving help() output; Python: implementing authentication decorators that keep original signatures.
Contextos
Python standard library, web frameworks (Flask, Django), any Python project using decorators.
Padrão
functools.wraps(original_func)(lambda *args, **kwargs: original_func(*args, **kwargs))
Estrutura central
functools.wraps(...)(lambda ...: ...(...))
Slots de substituição
original_func: callable, args: tuple, kwargs: dict
Colocados típicos
- @decorator syntax
- def wrapper(*args
- **kwargs):
- functools.partial
Substituições comuns
- Manual copying of __name__
- __doc__
- etc.: more verbose but avoids import
- class-based descriptors: more flexible but heavier.
Erros comuns
Forgetting to import functools: causes NameError when wraps is referenced; using wraps without parentheses: results in TypeError because wraps expects a function argument; applying wraps to a class instead of a function: leads to AttributeError as classes lack __wrapped__; omitting *args, **kwargs in the wrapper: causes the decorated function to lose arguments; returning an incorrect value from the lambda: breaks the original function's behavior.
Similar / contraste
functools.partial: fixes arguments rather than preserving metadata; class decorators: modify class behavior instead of function metadata; closure-based decorators: similar pattern but require manual metadata copying.
Interferências
Coming from Java: may rely on annotations instead of wrapper functions — Python uses functools.wraps for metadata preservation; Coming from JavaScript: may assume function.name is immutable — Python's __name__ is mutable and needs wrapping.
Família do chunk
- functools.partial
- decorator syntax
- closure decorators
- class decorators
Nuance
Do not use when you need to alter the function signature, as wraps only copies selected attributes; the performance overhead is negligible, typically a few microseconds per call; wraps only copies __module__, __name__, __qualname__, __doc__, and __annotations__, leaving other attributes unchanged.
Efeito pragmático
Enables reliable debugging, introspection, and help() on decorated functions; prevents confusion in large codebases where decorators obscure function identity.
Dica de memória
Like giving an actor a costume that doesn't hide their face — the audience still knows who they are.
Upgrade path
Creating class-based decorators or using functools.singledispatch for more complex dispatch.
Log in to save chunks.