What are decorators in Python and how would you write one?
A decorator is a function that takes a function and returns a replacement, letting you add behaviour without editing the original. The @ syntax is sugar: @log above def f means f = log(f).
import functools, time
def timed(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
try:
return func(*args, **kwargs)
finally:
print(f"{func.__name__} took {time.perf_counter()-start:.3f}s")
return wrapper
@timed
def slow(): ...The details that matter:
functools.wrapsis not optional. Without it the wrapper replaces the original's__name__,__doc__, and signature, which breaks introspection, documentation tools, and some frameworks.*args, **kwargsso the decorator works on any signature.- A decorator that takes arguments needs one more layer — a function returning a decorator returning a wrapper.
Where they are genuinely used: route registration in Flask and FastAPI, @property, @staticmethod, @functools.lru_cache for memoisation, retries, authentication checks, and logging.





