Code Reference

Decorators

Python · Reference cheat sheet

Decorators

Python · Reference cheat sheet


📋 Overview

A decorator is a callable that wraps another callable to add behavior (logging, timing, caching, auth). Syntax @decorator above def/class is sugar for f = decorator(f). Preserve metadata with functools.wraps.

🔧 Core concepts

PieceRole
@decf = dec(f)
@dec(args)f = dec(args)(f) — factory
functools.wrapsCopy __name__, __doc__, annotations
functools.lru_cacheMemoization
functools.cacheUnbounded cache (3.9+)
Class decoratorsTransform / register classes
StackedApplied bottom-up

Decorators work on methods too; be careful with self and descriptors.

💡 Examples

Simple wrapper:

import functools
import time
from collections.abc import Callable
from typing import TypeVar

F = TypeVar("F", bound=Callable[..., object])

def timed(fn: F) -> F:
    @functools.wraps(fn)
    def wrapper(*args: object, **kwargs: object) -> object:
        start = time.perf_counter()
        try:
            return fn(*args, **kwargs)
        finally:
            print(f"{fn.__name__}: {time.perf_counter() - start:.4f}s")
    return wrapper  # type: ignore[return-value]

@timed
def work(n: int) -> int:
    return sum(range(n))

Decorator with arguments:

def repeat(times: int):
    def deco(fn: Callable[..., object]) -> Callable[..., object]:
        @functools.wraps(fn)
        def wrapper(*args: object, **kwargs: object) -> object:
            result = None
            for _ in range(times):
                result = fn(*args, **kwargs)
            return result
        return wrapper
    return deco

@repeat(3)
def ping() -> str:
    print("ping")
    return "ok"

Built-ins:

from functools import cache, lru_cache

@cache
def fib(n: int) -> int:
    return n if n < 2 else fib(n - 1) + fib(n - 2)

@lru_cache(maxsize=128)
def load(key: str) -> str:
    return key.upper()

⚠️ Pitfalls

  • Forgetting @wraps breaks introspection, tests, and OpenAPI tools.
  • Order of stacked decorators matters (@a then @ba(b(f))).
  • Caching mutable/unhashable args fails with lru_cache.
  • Decorating instance methods: wrapper still receives self as first arg.
  • Class decorators replace the class object — return the class (or a new one).

On this page