Creating Parameterized Decorators
Explore how to create parameterized decorators that accept arguments to customize their behavior. Understand the decorator factory pattern, its three-level structure, and how to apply it to build configurable tools like retry mechanisms and role-based access control. This lesson also covers best practices using functools.wraps to preserve function metadata, enabling clean and reusable Python code.
Decorators can wrap functions to add logging, timing, or validation. So far, the decorators shown have been rigid. They always apply the same behavior. For example, a @retry decorator might retry a failed operation three times if that value is hardcoded. However, different functions may require different retry limits. A critical operation may require ten retries, while a quick UI update may require only one. Creating a separate decorator for every configuration is not practical. To address this, decorators can accept arguments that configure their behavior when they are applied.
The decorator factory pattern
To pass arguments to a decorator, we must introduce an additional layer of nesting. A standard decorator is a function that accepts a function and returns a wrapper. A parameterized decorator is actually a function that accepts arguments and returns a decorator. This outer function is often called a decorator factory because its sole job is to manufacture the actual decorator based on the settings we provide.
This creates a structure with three distinct levels:
The factory: Accepts configuration arguments (e.g.,
retries=3...