Decorators are functions that modify other functions behavior. The @decorator syntax is syntactic sugar for wrapping: @decorator is equivalent to func = decorator(func).
A basic decorator takes a function, defines a wrapper that adds behavior, and returns the wrapper. The functools.wraps decorator preserves the original function metadata. Always use it.
Practical decorators: @timer (measure execution time), @retry(max_attempts=3), @cache or @lru_cache (memoize results), @login_required, and @validate_input.
Decorator factories are decorators that take arguments: @repeat(n) calls a function n times. They return the actual decorator.
Understanding decorators is crucial for reading Python code, especially in web frameworks and testing libraries where they are ubiquitous.