What Is a Decorator in Python? Explained With Examples

A Python decorator wraps a function to add behavior before or after it runs, without changing the function's own code. Learn the @ syntax and how it works.

Published September 17, 2026

A decorator is a function that takes another function as input and returns a new function that adds behavior around it. The @decorator syntax placed above a function definition is shorthand for reassigning the function to the decorator's return value.

Common causes

  • Cross-cutting concerns like logging, timing, caching, or access control often need to wrap many different functions without duplicating that logic inside each one

How to fix it

  • Write a decorator as a function that defines and returns an inner 'wrapper' function calling the original
  • Use functools.wraps(func) on the wrapper to preserve the original function's name and docstring for debugging and introspection
  • Use built-in decorators like @staticmethod, @classmethod, and @property for common patterns rather than writing your own

Example

import functools

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        import time
        start = time.time()
        result = func(*args, **kwargs)
        print(f'{func.__name__} took {time.time() - start:.4f}s')
        return result
    return wrapper

@timer
def slow():
    ...

FAQ

Why use functools.wraps in a decorator?

Without it, the wrapped function's __name__ and __doc__ get replaced by the wrapper's — functools.wraps copies that metadata over so debugging tools and documentation still show the original function's identity.

More Python articles