Коротко

Декоратор — функция (или класс), которая принимает другую функцию и возвращает обёртку с дополнительной логикой. Синтаксис @decorator.

def timer(fn):
    def wrapper(*args, **kwargs):
        print("start", fn.__name__)
        return fn(*args, **kwargs)
    return wrapper

@timer
def work(x):
    return x * 2

@timer выше work — то же, что work = timer(work).

Зачем

Логирование, проверка прав, кэш (functools.lru_cache), retry — без дублирования кода.

Короткий ответ

«Декоратор оборачивает функцию, добавляя поведение. @f означает func = f(func). Часто используют *args/**kwargs и functools.wraps.»