Preserving Function Metadata
When you decorate a function, it gets replaced by wrapper. This loses the original name and docstring:
@my_decorator
def add(a, b):
"""Add two numbers."""
return a + b
print(add.__name__) # "wrapper" - not "add"!
print(add.__doc__) # None - docstring is lost!
Fix this with @functools.wraps:
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
Now the decorated function keeps its identity:
print(add.__name__) # "add"
print(add.__doc__) # "Add two numbers."
Always use @wraps in your decorators. It's essential for debugging, documentation, and introspection tools.
I cover functools.wraps in my Python Decorators course.