Introduction
Python decorators are a powerful feature that allows you to modify the behavior of functions or classes dynamically. Decorators provide a way to add functionality to existing code without modifying the original source. This blog post will delve into the concept of decorators in Python, starting from the basics and gradually progressing to more advanced techniques.
Understanding Decorators
Function Decorators
Function decorators are a way to modify the behavior of a function by wrapping it inside another function. The decorator function takes the original function as an argument, adds some functionality, and returns a modified function. This allows you to enhance or extend the behavior of functions without modifying their source code.
def uppercase_decorator(func):
def wrapper():
result = func()
return result.upper()
return wrapper
@uppercase_decorator
def say_hello():
return "Hello, World!"
print(say_hello()) # Output: HELLO, WORLD!
In the example above, the uppercase_decorator
function is defined to wrap the say_hello
function. It modifies the behavior by converting the returned string to uppercase. The @uppercase_decorator
syntax is used to apply the decorator to the say_hello
function.
Class Decorators
Class decorators are similar to function decorators but operate on classes instead of functions. They allow you to modify the behavior or add functionality to a class. The decorator function takes the original class as an argument, creates a derived class with added functionality, and returns the modified class.
def add_method_decorator(cls):
def new_method(self):
return "New method added!"
cls.new_method = new_method
return cls
@add_method_decorator
class MyClass:
def existing_method(self):
return "Existing method called!"
obj = MyClass()
print(obj.existing_method()) # Output: Existing method called!
print(obj.new_method()) # Output: New method added!
In the example above, the add_method_decorator
function wraps the MyClass
class and adds a new method called new_method
. The @add_method_decorator
syntax is used to apply the decorator to the MyClass
class.
Decorator Syntax and Execution
When using decorators, it’s important to understand the order of execution. Decorators are applied from the bottom up, meaning the decorator defined at the top is executed last. This order is crucial when multiple decorators are applied to the same function or class.
def decorator1(func):
print("Decorator 1 executed")
return func
def decorator2(func):
print("Decorator 2 executed")
return func
@decorator1
@decorator2
def my_function():
print("Inside my_function")
my_function()
Output:
Decorator 2 executed
Decorator 1 executed
Inside my_function
In the example above, the decorator2
decorator is executed first, followed by the decorator1
decorator. The my_function
is then called, and the output reflects the order of execution.