Skip to main content

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!