Python ยท Chapter 31 of 45

Python Decorators

A DECORATOR is a function that wraps another function, adding behaviour before or after it. Use with `@decorator` syntax.

Common uses: logging, timing, caching, access control, and Flask/Django route registration.

How they work

A decorator takes a function and returns a new function. `@deco` above `def f():` is short for `f = deco(f)`.

functools.wraps

Use `@functools.wraps(func)` inside your decorator so the wrapped function keeps its original name and docstring.

Example 1 (python)
def log(func):
    def wrapper(*args, **kw):
        print(f"calling {func.__name__}")
        return func(*args, **kw)
    return wrapper

@log
def add(a, b):
    return a + b

print(add(2, 3))
Output
calling add
5

Wraps add() with a logging step.

Example 2 (python)
from functools import lru_cache

@lru_cache
def fib(n):
    return n if n < 2 else fib(n-1) + fib(n-2)

print(fib(30))
Output
832040

lru_cache caches results โ€” massive speedup for recursive functions.

Key points

  • Function that wraps another function.
  • Syntax: `@decorator` above `def`.
  • Use `functools.wraps` to preserve metadata.
  • Common built-ins: `@staticmethod`, `@classmethod`, `@property`, `@lru_cache`.
๐Ÿ’ก Note: Decorators run at function-definition time, not each call โ€” but the wrapper they return runs every call.

๐Ÿ“ Quick Quiz

1. The decorator syntax uses which symbol?

2. `@lru_cache` provides:

3. A decorator is essentially: