Chain Multiple Decorators in Python (original) (raw)

Decorator chaining is the process of applying multiple decorators to a single function. Each decorator wraps the function and adds its own functionality, allowing multiple behaviors to be combined without modifying the original code. Following sections explains how decorator chaining works, the order of execution and how multiple decorators interact with one another.

**Example: Chaining Multiple Decorators

Python `

def decorator1(func): def wrapper(): print("Decorator 1 - Before Function") func() print("Decorator 1 - After Function") return wrapper

def decorator2(func): def wrapper(): print("Decorator 2 - Before Function") func() print("Decorator 2 - After Function") return wrapper

@decorator1 @decorator2 def greet(): print("Hello, World!")

greet()

`

Output

Decorator 1 - Before Function Decorator 2 - Before Function Hello, World! Decorator 2 - After Function Decorator 1 - After Function

Decorator

A decorator is a function that can take a function as an argument and extend its functionality and return a modified function with extended functionality.

2

Order of Execution in Decorator Chaining

When multiple decorators are used, Python applies them from the bottom up. The decorator closest to the function is applied first, and the resulting function is then passed to the decorator above it. This order determines how the decorators interact and affect the final behavior of the function.

**Example:

Python `

@decor1 @decor2 def num(): return 10

`

is equivalent to:

Python `

num = decor1(decor2(num))

`

Here, decor2 wraps the original num() function first, and the function returned by decor2 is then wrapped by decor1.

**Explanation:

**Syntax of decorator:

@decor1
@decor2
def num():
pass

**Example 1: Two decorators are applied to num() to demonstrate decorator chaining. Python applies decorators from the bottom up, so @decor executes first and its result is then passed to @decor1 for further processing.

Python `

code for testing decorator chaining

def decor1(func): def inner(): x = func() return x * x return inner

def decor(func): def inner(): x = func() return 2 * x return inner

@decor1 @decor def num(): return 10

print(num())

`

**Explanation:

**Example 2: Multiple decorators are applied to sayhellogfg() to show how decorator chaining works. Each decorator contributes its own behavior, resulting in a combined effect when the function is executed.

Python `

def decor1(func): def wrap(): print("") func() print("") return wrap def decor2(func): def wrap(): print("@@@@@@@@@@@@") func() print("@@@@@@@@@@@@") return wrap

@decor1

@decor2 def sayhellogfg(): print("Hello") def saygfg(): print("GeekforGeeks")

sayhellogfg() saygfg()

`

Output


@@@@@@@@@@@@ Hello @@@@@@@@@@@@


GeekforGeeks

**Explanation:

Decorators With Arguments

Decorators can also accept arguments, allowing their behavior to be customized when applied to a function. These decorators return another decorator function, which then wraps the target function. Multiple parameterized decorators can be chained in the same way as regular decorators.

**Example:

Python `

def repeat(times): def decorator(func): def wrapper(): for _ in range(times): func() return wrapper return decorator

def message(text): def decorator(func): def wrapper(): print(text) func() return wrapper return decorator

@message("Welcome") @repeat(2) def greet(): print("Hello")

greet()

`