Python decorators are a powerful feature that allows you to modify the behavior of functions or classes without altering their source code. Here’s a detailed guide on how to use Python decorators effectively:
Understanding Decorators
A decorator is a function that takes another function as an argument, adds some functionality, and returns a new function. This allows you to "wrap" another function to extend its behavior without modifying the original function's source code.
Basic Syntax
The basic syntax for using a decorator is:
@decorator_function
def some_function():
def some_function():
some_function = decorator_function(some_function)
Example of a Simple Decorator
Here’s a simple example of a decorator that adds some text before and after the execution of a function:
def simple_decorator(func):
def wrapper():
print("Before the function is called.")
func()
print("After the function is called.")
return wrapper
@simple_decorator
def say_hello():
print("Hello!")
say_hello()
Before the function is called.
Hello!
After the function is called.
Decorators with Parameters
Decorators can also take parameters. This allows for more flexibility and customization. Here’s an example:
def repeat(number_of_times):
def decorator_repeat(func):
def wrapper(*args, **kwargs):
for _ in range(number_of_times):
func(*args, **kwargs)
return wrapper
return decorator_repeat
@repeat(3)
def say_hello():
print("Hello!")
say_hello()
Hello!
Hello!
Hello!
Preserving Function Metadata with functools.wraps
When you use a decorator, the original function’s metadata (like __name__
and __doc__
) is lost. To preserve this information, use functools.wraps
:
import functools
def simple_decorator(func):
@functools.wraps(func)
def wrapper():
print("Before the function is called.")
func()
print("After the function is called.")