The Basics:
Python decorators are a powerful and flexible feature that allows developers to modify or extend the behavior of functions or methods. Decorators provide a clean and concise way to wrap or enhance functions, making them an essential tool in a Python developer’s toolkit. In this blog post, we’ll delve into the fundamentals of decorators, understand their syntax, and explore practical examples of how to write and use decorators effectively.
Understanding Decorators:
In Python, a decorator is a function that takes another function as input and extends or modifies its behavior. Decorators are applied using the “@” symbol followed by the decorator’s name, placed above the function definition. They allow developers to separate concerns and add functionality without altering the original function.
Writing a Simple Decorator:
Let’s start with a basic example of a decorator that logs the arguments and return value of a function:
def log_function_call(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) print(f"Function {func.__name__} called with arguments {args} and keyword arguments {kwargs}") print(f"Returned: {result}") return result return wrapper @log_function_call def add(a, b): return a + b result = add(3, 5)
In this example, the log_function_call
decorator wraps the add
function, printing information about its arguments and return value. The output will be:
Function add called with arguments (3, 5) and keyword arguments {} Returned: 8
Decorators with Parameters:
Decorators can also accept parameters, allowing for greater flexibility. Here’s an example of a decorator that repeats a function call a specified number of times:
def repeat(n): def decorator(func): def wrapper(*args, **kwargs): for _ in range(n): result = func(*args, **kwargs) print(f"Function {func.__name__} called with arguments {args} and keyword arguments {kwargs}") print(f"Returned: {result}") return result return wrapper return decorator @repeat(3) def multiply(a, b): return a * b result = multiply(4, 6)
This will execute the multiply
function three times and print the details for each call.
Common Use Cases:
Decorators are widely used for tasks such as logging, authentication, and memoization. For instance, a memoization decorator can cache the results of expensive function calls to improve performance:
from functools import lru_cache @lru_cache(maxsize=None) def fibonacci(n): if n <= 1: return n return fibonacci(n - 1) + fibonacci(n - 2)