PythonDecorators

Python Decorators Learning Path

68 tutorials & guides intermediate / advanced

Decorators are one of Python's most expressive features. The @ syntax looks deceptively simple, but understanding what happens underneath -- closures, higher-order functions, function objects, and the execution order when stacking -- is what separates developers who use decorators confidently from those who copy patterns without knowing why they work.

This collection covers the full decorator landscape: from writing your first wrapper function through functools.wraps, parameterized decorators, class-based decorators, and the built-in patterns like @property, @staticmethod, and @classmethod. Each article includes working code you can run and modify.

01

Foundations and Syntax

13 articles

Python Decorators Demystified: From First Principles to Real-World Patterns

How decorators work under the hood, building your own from scratch, using arguments, stacking decorators, and applying real-world patterns like timing, logging, authentication, and rate limiting.

Intermediate read()

What is a Python Decorator

What a Python decorator is from the ground up: first-class functions, closures, the @ syntax, writing custom decorators, handling arguments, functools.wraps, stacking, built-in decorators, and practical examples.

Beginner read()

Python Decorator Syntax

Python decorator syntax from the ground up: the @ symbol, first-class functions, closures, functools.wraps, stacking, parameterized decorators, and class-based decorators with complete code examples.

Beginner read()

When Should I Use Python Decorators

When to use Python decorators and when to avoid them, covering logging, caching, retry logic, authentication, input validation, and rate limiting with full code examples.

Intermediate read()

Python Decorators: Use Case Examples

Ten practical Python decorator use cases with full code: execution timing, call logging, memoization, input validation, rate limiting, access control, retry logic, singleton pattern, deprecation warnings, and debug tracing.

Intermediate read()

TypeError: wrapper() takes 0 positional arguments but 1 was given

Fix the Python TypeError where wrapper() takes 0 positional arguments but 1 was given, covering all six causes: missing *args/**kwargs, missing self in class methods, parameterized decorator mistakes, class-based decorators, and shadowed builtins.

Beginner read()

What Does the @ Symbol Do in Python

The @ symbol in Python has two distinct uses: decorator syntax for wrapping functions and the matrix multiplication operator introduced in Python 3.5, with full code examples for both.

Beginner read()

The Fundamental Rule That Allows Functions to Be Passed as Arguments

Why Python functions can be passed as arguments, assigned to variables, and returned from other functions, covering the object model, PyObject internals, callable protocol, closures, and higher-order function patterns.

Beginner read()

A Decorator Is Simply a Function That Takes Another Function as an Argument

A Python decorator is a function that takes another function as its argument, adds behavior, and returns a new function. This beginner guide builds the concept from first-class functions through closures to the full decorator pattern.

Beginner read()

Python Decorators: Higher-Order Functions

How Python decorators are higher-order functions, covering functions as arguments, functions as return values, map/filter/sorted patterns, function factories, and how decorators combine both higher-order patterns into a single mechanism.

Beginner read()

Python Decorator Closures

How closures power Python decorators, covering free variables, cell objects, __closure__ inspection, nonlocal for mutable state, parameterized decorator closures, and the variable lookup chain with runnable code examples.

Intermediate read()

Python Decorator Execution Order

The two-phase execution order of a single Python decorator: decoration time vs call time, what the @ syntax desugars to, which code runs at module import, which runs on every call, and how to trace execution with print statements.

Beginner read()

Python Decorator Function Objects: The Attributes That Make Decorators Work

Python functions are objects with attributes like __name__, __doc__, __code__, __closure__, and __dict__. How decorators interact with these attributes, why decoration disrupts them, and how functools.wraps restores identity.

Intermediate read()
02

functools and Preserving Metadata

18 articles

functools.pipe — The Case for Function Composition in Python's Standard Library

The proposed functools.pipe utility for Python, tracing the full history of function composition debates, PEP proposals, and how to implement robust pipelines in your code today.

Advanced read()

What is functools in Python

A complete guide to Python's functools module covering lru_cache, cache, cached_property, partial, reduce, wraps, total_ordering, singledispatch, and the Placeholder sentinel added in Python 3.14.

Intermediate read()

How to Preserve Function Name and Docstring in Python Decorators

How to preserve function name, docstring, and metadata in Python decorators using functools.wraps, what __wrapped__ does, why inspect.signature follows it, and what breaks when metadata is lost.

Beginner read()

Why Does My Decorated Function Show "wrapper" as Its Name?

Why Python decorated functions lose their original name and show wrapper instead, how to fix it with functools.wraps, access the original via __wrapped__, and handle edge cases in stacked and class-based decorators.

Beginner read()

How to Use @functools.wraps(func) Inside a Decorator

Step-by-step guide to using @functools.wraps(func) inside every type of Python decorator: simple, parameterized, class-based, stacked chains, and async wrappers, with a complete boilerplate template.

Beginner read()

Python Decorator Losing Original Function Metadata Fix

Fix the common Python problem where decorators cause functions to lose their __name__, __doc__, and signature. Diagnose metadata loss, apply functools.wraps, verify the fix, and handle edge cases in stacked and class-based decorators.

Beginner read()

How to Access the Original Function from a Decorated Function Using __wrapped__

How to access the original function from a decorated function using Python's __wrapped__ attribute, covering functools.wraps, inspect.unwrap, bypassing decorators in tests, lru_cache bypass, and stacked chains.

Beginner read()

Difference Between functools.wraps and functools.update_wrapper

The difference between functools.wraps and functools.update_wrapper in Python, which to use for function decorators, class-based decorators, and partial objects with complete code examples and CPython source analysis.

Beginner read()

Fixing Broken help() Output for Decorated Python Functions

Why help() shows the wrong name, signature, and docstring for decorated Python functions, and how to fix it with functools.wraps, update_wrapper, and the wrapt library.

Intermediate read()

Using functools.wraps with Class-Based Decorators

How to preserve function metadata in Python class-based decorators using functools.update_wrapper, covering stateful decorators, parameterized class decorators, the descriptor protocol for method binding, and comparison with function-based decorators.

Intermediate read()

Python functools.wraps Equivalent for Classes

How to preserve function metadata in class-based decorators using functools.update_wrapper, the equivalent of functools.wraps for classes, covering the descriptor protocol, __get__ for method binding, and decorating classes themselves.

Intermediate read()

Standard Template for Well-Behaved Python Decorators

Five copy-ready Python decorator templates covering the basic pattern, parameterized decorators, optional-argument decorators, class-based decorators, and type-safe decorators using ParamSpec from PEP 612.

Intermediate read()

Using functools.wraps with Decorators That Take Arguments

How to correctly apply functools.wraps inside parameterized Python decorators that accept arguments, covering the three-layer nesting pattern, where to place @wraps, common mistakes, and real-world examples.

Beginner read()

functools.wraps vs decorator Module for Signature Preservation

Comparing functools.wraps, the decorator module, wrapt, and boltons.funcutils for preserving function signatures in Python decorators, with code examples, error message comparisons, and a decision guide.

Advanced read()

How to Copy Custom Attributes from Wrapped Function to Decorator

How to copy custom attributes from a wrapped function to a decorator wrapper in Python, covering __dict__ merging, timing issues, adding new attributes, extending WRAPPER_ASSIGNMENTS, and building attribute-aware decorators.

Intermediate read()

Debugging Decorated Functions with Missing Metadata in Stack Traces

How to debug Python decorated functions that show "wrapper" in stack traces, logging output, help(), pdb, and pickle. Fix missing metadata with functools.wraps, diagnose broken chains, and build diagnostic utilities.

Beginner read()

How to Use functools.wraps to Preserve Metadata in Complex Stacks

How functools.wraps propagates metadata through multi-decorator stacks, how the __wrapped__ chain works with inspect.unwrap, where wraps must be placed in parameterized and class-based decorators, and how to extend WRAPPER_ASSIGNMENTS for custom attributes.

Advanced read()

Using functools.partial to Simplify Decorator Syntax

How functools.partial eliminates triple-nested functions in Python decorators. Build decorators that work with and without arguments using partial to pre-fill parameters, with full code examples.

Intermediate read()
03

Parameterized and Stacked Decorators

17 articles

Writing Parameterized Decorators in Python: The Three-Layer Factory Pattern Explained

How to write parameterized decorators using the three-layer factory pattern, closures, functools.wraps, optional-argument decorators, class-based factories, ParamSpec type hints, and production patterns like retry, rate limiting, and access control.

Intermediate read()

How Python Decorator Stacking Works: Execution Order, Binding, and the Onion Model

How stacked Python decorators bind bottom-up at definition time and execute top-down at call time, the onion model, functools.wraps across the stack, and ordering patterns for authentication, caching, and logging chains.

Intermediate read()

What is Python Decorator Stacking

What Python decorator stacking is, how bottom-up binding and top-down execution work, why order matters, and how to compose decorator chains correctly with practical code examples.

Beginner read()

Building a Python @retry Decorator with Exponential Backoff and Configurable Exceptions

Build a production-grade Python @retry decorator with exponential backoff, configurable exceptions, jitter, and logging, with full code examples and comparisons with tenacity and backoff libraries.

Intermediate read()

Python Decorator Patterns for Logging, Caching, and Rate Limiting in Production Code

Production-ready Python decorator patterns for structured logging, result caching, and rate limiting with full code examples, comparison tables, and best practices using functools.wraps.

Intermediate read()

Nesting Multiple Decorators in Python Order of Execution

The two-phase model of stacked Python decorators: bottom-to-top wrapping at definition time and top-to-bottom execution at call time, with code traces, real-world ordering mistakes, and Flask-specific rules.

Intermediate read()

Python Decorators: Common Backend Tasks

Production-ready Python decorators for six common backend tasks: structured logging, authentication, input validation, caching with TTL, retry with exponential backoff, and execution timing with complete annotated code.

Intermediate read()

Real World Examples of Python Decorators for Logging and Auth

Production-ready Python decorator examples for structured logging, execution timing, audit trails, JWT authentication, role-based access control, and API key validation with complete code.

Intermediate read()

Troubleshooting Decorator Arguments vs Function Arguments

Troubleshoot the common confusion in Python decorators: which arguments belong to the decorator and which belong to the decorated function, covering two-layer vs three-layer nesting, missing parentheses, and a visual layer map.

Intermediate read()

Understanding How Stacking Decorators Affects the Final Function

How stacking multiple Python decorators affects the final function, covering bottom-to-top application order, top-to-bottom execution flow, the @classmethod descriptor trap, metadata propagation, and practical stacking patterns.

Intermediate read()

Python Decorators: Execution of the "Before" Code

How Python decorator "before" code executes prior to the wrapped function call, covering pre-execution patterns for logging, validation, authentication, timing, and conditional gating with full code examples.

Intermediate read()

How to Chain Decorators in Python

How to chain multiple Python decorators on a single function, covering stacking syntax, application order vs execution order, parameterized chains, metadata preservation, and production patterns.

Intermediate read()

Implementing Decorators That Can Be Used Both With and Without Parentheses

How to build Python decorators that work both with and without parentheses using callable detection, functools.partial, keyword-only arguments, and class-based patterns with full code examples.

Intermediate read()

Chained Decorator Execution Order

How Python evaluates chained decorators from bottom-to-top during wrapping and top-to-bottom during execution, covering the onion model, functools.wraps, parameterized chains, class-based decorators, and real-world ordering pitfalls.

Intermediate read()

Python Syntax Required to Pass Custom Parameters Into the Decorator Itself

The exact Python syntax for passing custom parameters into a decorator, covering the three-level nested function pattern, decorator factories, class-based decorators with arguments, the functools.partial shortcut, and common mistakes.

Intermediate read()

Python Decorator Factory with Arguments

How Python decorator factories use three layers of nested functions to accept arguments and return configurable decorators, covering closures, functools.wraps, the optional-arguments pattern, class-based factories, and type-safe factories with ParamSpec.

Intermediate read()

Python Decorator for Timing Function Execution

Build a Python timing decorator from scratch using time.perf_counter, covering basic to advanced implementations including logging integration, threshold filtering, statistics collection, async support, and context manager hybrids.

Intermediate read()
04

Class-Based Decorators and Built-Ins

20 articles

Python @classmethod: What cls Does, Factory Methods, and When to Use It

What cls really is, how class methods differ from static methods, how factory methods work, and why inheritance changes everything about how @classmethod behaves.

Intermediate read()

Python @dataclass: The Decorator That Writes Your Boilerplate For You

How @dataclass generates __init__, __repr__, and __eq__ from type annotations, the field() function, __post_init__ validation, frozen and slotted dataclasses, kw_only fields, inheritance patterns, and when to reach for dataclasses vs Pydantic.

Intermediate read()

What It Means to Shadow a Class Method in Python

How instance attributes can silently block access to a @classmethod, why @classmethod is a non-data descriptor, how Python's attribute lookup order makes this possible, and how to avoid it.

Intermediate read()

Python Class Decorators vs Metaclasses Use Cases

When to use Python class decorators vs metaclasses with practical code examples covering singletons, registries, validation, method wrapping, and the modern __init_subclass__ alternative.

Advanced read()

How to Use @property Decorator for Getters and Setters

How to use Python's @property decorator to create managed attributes with getter, setter, and deleter methods, covering computed properties, read-only attributes, validation, inheritance, and the underlying descriptor protocol.

Intermediate read()

Difference Between @staticmethod and @classmethod in Python

The difference between @staticmethod and @classmethod in Python with code examples, covering when to use each, how they work as descriptors, factory methods, inheritance behavior, and common mistakes.

Intermediate read()

Python @dataclass vs Manual __init__ Boilerplate

Side-by-side comparison of Python @dataclass decorator versus manually writing __init__, __repr__, and __eq__, covering auto-generated methods, field defaults, __post_init__, frozen and slotted dataclasses, and when to use each approach.

Intermediate read()

How to Make a Class Instance Behave Like a Callable Decorator

How to build class-based decorators in Python using __call__, covering stateful decorators, functools.update_wrapper, parameterized class decorators, the descriptor protocol for method support, and when to choose classes over closures.

Intermediate read()

Class-Based Decorator with Arguments vs Function Decorator

Comparing class-based decorators with arguments against function-based decorator factories in Python, with side-by-side code showing __init__/__call__ versus triple-nested functions, state management, testing, and when to choose each.

Intermediate read()

Differentiating How a Class-Based Decorator Handles the self Argument in Instance Methods

Why class-based decorators lose the instance self argument when decorating methods, how the descriptor protocol fixes it with __get__, and how to build decorators that work on both standalone functions and instance methods.

Advanced read()

Standard List of Built-in and Core Module Decorators in Python

Complete reference of every built-in and standard library decorator in Python, organized by module, covering builtins, functools, dataclasses, contextlib, abc, typing, and atexit with code examples for each.

Intermediate read()

Python Decorator: Ways to Speed Up Recursions Using Built-in Caching

Speed up recursive Python functions using built-in caching decorators, covering functools.lru_cache and functools.cache, manual memoization, cache_info and cache_clear, the typed parameter, recursion depth limits, and bounded vs unbounded caching.

Intermediate read()

Python Decorators: Built-in Functions (Global Scope)

A complete reference to Python's built-in decorators available in global scope without imports: @property, @staticmethod, and @classmethod, plus standard library functools decorators including @wraps, @lru_cache, @cached_property, and @total_ordering.

Beginner read()

@contextmanager: Create a with Statement Context Manager Using a Simple Generator Function

How Python's @contextmanager decorator converts a generator function into a with statement context manager, covering the yield contract, exception handling, yielding values, using context managers as decorators, and async support.

Intermediate read()

@abstractmethod: Requiring Subclasses to Implement a Method Before They Can Be Instantiated

How Python's @abstractmethod decorator forces subclasses to implement required methods before instantiation, covering ABC inheritance, abstract properties, combining with @classmethod and @staticmethod, and abstract vs duck typing.

Intermediate read()

Register a Function to Be Executed Automatically When the Python Interpreter Exits with @register

How to use Python's atexit.register as a decorator to automatically execute cleanup functions when the interpreter exits, covering LIFO execution order, unregister(), and practical examples for temp file cleanup and connection management.

Intermediate read()

Core Standard Library Decorators

A thorough technical guide to Python's core standard library decorators from functools, covering @wraps, @lru_cache, @cache, @cached_property, @singledispatch, and @total_ordering with real code examples.

Intermediate read()

Python Specialized Utility Decorators

A guide to Python's specialized utility decorators including functools.lru_cache, functools.singledispatch, functools.total_ordering, functools.cached_property, contextlib.contextmanager, and custom patterns for retry logic, rate limiting, and type enforcement.

Intermediate read()

Python @unique: Ensuring No Two Members in an Enum Class Have the Same Value

How Python's @unique decorator enforces distinct member values in Enum classes by raising a ValueError when duplicate values create aliases, with code examples for IntEnum, StrEnum, and the newer @verify(UNIQUE) pattern.

Intermediate read()

Python @unittest.mock.patch: Replacing Real Objects with Mock Objects During a Test Run

How Python @unittest.mock.patch works: temporarily replacing real objects with mock objects during a test run, covering patch targets, context managers, patch.object, patch.dict, autospec, side_effect, and return_value.

Intermediate read()

How to Learn Python Decorators

1

Learn How Functions Work as Objects

Before writing a decorator, you need to understand that functions in Python are first-class objects. They can be assigned to variables, passed as arguments, and returned from other functions. This is the foundation that makes decorators possible.

2

Understand Closures and Higher-Order Functions

A closure is a nested function that captures variables from its enclosing scope. A higher-order function is a function that takes another function as an argument or returns one. Decorators rely on both of these mechanisms to wrap behavior around existing functions.

3

Write Your First Decorator Using the @ Syntax

Start by writing a simple wrapper function that accepts a function, defines an inner function, and returns it. Apply it using the @decorator_name syntax above a function definition. This is syntactic sugar for reassigning the function to the decorator's return value.

4

Preserve Metadata with functools.wraps

Without @functools.wraps, a decorated function loses its original __name__, __doc__, and other metadata. Always apply @functools.wraps(func) to the inner wrapper function to copy these attributes from the original function to the wrapper.

5

Explore Parameterized, Stacked, and Class-Based Patterns

Once you are comfortable with basic decorators, move on to parameterized decorators (which require an extra layer of nesting), stacking multiple decorators on a single function (execution order matters), and class-based decorators using __call__. Then study built-in decorators like @property, @staticmethod, @classmethod, and @dataclass.

Frequently Asked Questions

What is a Python decorator?

A decorator is a function that takes another function as its argument, extends or modifies its behavior, and returns the modified function. The @ syntax placed above a function definition is shorthand for passing that function through the decorator and reassigning the result to the same name.

Why do I need functools.wraps in my decorators?

When you wrap a function inside a decorator, the wrapper replaces the original function's identity. Without @functools.wraps, the decorated function's __name__, __doc__, and __qualname__ all point to the inner wrapper instead of the original function. This causes problems with debugging tools, documentation generators, serialization with pickle, and any code that relies on function introspection.

What is the difference between @staticmethod and @classmethod?

@staticmethod defines a method that does not receive the instance (self) or the class (cls) as its first argument. It behaves like a plain function that happens to live inside a class. @classmethod receives the class itself as its first argument (cls), which means it can access and modify class-level state and works correctly with inheritance, since cls refers to the subclass when called on one.

How does decorator stacking order affect execution?

When you stack multiple decorators on a function, the decorator closest to the function definition is applied first, and the outermost decorator wraps everything. At call time, execution flows from the outermost wrapper inward to the original function, then back out. The order you list decorators directly determines the order in which their pre-call and post-call logic runs.

What is a parameterized decorator and how does it work?

A parameterized decorator is a decorator that accepts its own arguments, such as @retry(max_attempts=3). It requires an extra layer of nesting: the outermost function accepts the parameters, returns a decorator function that accepts the target function, which in turn returns the inner wrapper. This three-level structure allows you to configure decorator behavior at the point of application.

When should I use @dataclass instead of writing __init__ manually?

Use @dataclass when your class is primarily a container for data with typed fields. The decorator generates __init__, __repr__, and __eq__ automatically from your type annotations, which eliminates boilerplate and reduces errors. For classes with complex initialization logic, custom validation beyond what __post_init__ supports, or behavior that diverges significantly from a data container pattern, writing __init__ manually gives you more control.

back to top