Decorators in Python
Hey there! In this guide, we'll explore decorators in Python. Decorators are a powerful and flexible way to modify the behavior of functions or methods. They allow you to add functionality to existing code in a clean and readable way. Let's dive in!
Python Decorators​
- Function Modification: Decorators allow you to extend or modify the behavior of functions or methods without changing their code.
- Higher-Order Functions: Decorators are often implemented as higher-order functions, meaning they take another function as an argument.
1. Defining a Simple Decorator​
You can define a simple decorator by creating a function that takes another function as an argument and returns a new function.
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
2. Applying a Decorator​
You can apply a decorator to a function using the @decorator_name
syntax above the function definition.
@my_decorator
def say_hello():
print("Hello!")
say_hello() # Output:
# Something is happening before the function is called.
# Hello!
# Something is happening after the function is called.
3. Decorators with Arguments​
You can create decorators that accept arguments by defining another level of nested functions.
def repeat(num_times):
def decorator_repeat(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return wrapper
return decorator_repeat
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
4. Using functools.wraps
​
When creating decorators, it's a good practice to use functools.wraps
to preserve the original function's metadata.
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("Something is happening before the function is called.")
return func(*args, **kwargs)
return wrapper
@my_decorator
def say_hello():
"""This function says hello."""
print("Hello!")
print(say_hello.__name__) # Output: say_hello
print(say_hello.__doc__) # Output: This function says hello.
5. Chaining Decorators​
You can apply multiple decorators to a single function by stacking them.
def decorator_one(func):
def wrapper():
print("Decorator One")
func()
return wrapper
def decorator_two(func):
def wrapper():
print("Decorator Two")
func()
return wrapper
@decorator_one
@decorator_two
def say_hello():
print("Hello!")
say_hello() # Output:
# Decorator One
# Decorator Two
# Hello!