Python Decorators
In Python programming, decorators are a powerful feature that allows you to modify or extend the behavior of functions or methods without changing their actual code.
They are widely used in frameworks like Flask, Django, logging systems, authentication, and performance tracking.
Think of decorators as a “wrapper” around a function that adds extra functionality before or after the function runs.
What is a Decorator in Python?
A decorator in Python is a function that:
- Takes another function as input
- Adds some functionality
- Returns a new function
In simple terms:
A decorator “decorates” a function with additional behavior.
Basic Syntax of Decorator
def my_decorator(func):
def wrapper():
print("Before function execution")
func()
print("After function execution")
return wrapper
@my_decorator
def say_hello():
print("Hello, World!")
say_hello()
Output:
Before function execution
Hello, World!
After function execution
How Decorators Work
When you write:
@my_decorator
def say_hello():
Python internally converts it to:
say_hello = my_decorator(say_hello)
So the function gets replaced by the wrapper function.
Why Use Decorators?
Decorators help in:
- Code reusability
- Separation of concerns
- Adding logging
- Authentication checks
- Performance monitoring
- Access control
Decorator with Arguments
If your function takes arguments, your decorator must handle them too.
def smart_decorator(func):
def wrapper(*args, **kwargs):
print("Function is about to run")
return func(*args, **kwargs)
return wrapper
@smart_decorator
def add(a, b):
return a + b
print(add(5, 3))
Output:
Function is about to run
8
Using functools.wraps
Without wraps, function metadata is lost.
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("Executing function")
return func(*args, **kwargs)
return wrapper
Why it matters:
- Keeps original function name
- Keeps documentation
- Keeps debugging information
Real-World Example: Logging Decorator
def log_function(func):
def wrapper(*args, **kwargs):
print(f"Calling function: {func.__name__}")
result = func(*args, **kwargs)
print(f"Finished execution of: {func.__name__}")
return result
return wrapper
@log_function
def multiply(a, b):
return a * b
print(multiply(4, 5))
Real-World Example: Authentication Check
def require_auth(func):
def wrapper(user):
if not user.get("is_logged_in"):
print("Access Denied!")
return
return func(user)
return wrapper
@require_auth
def view_dashboard(user):
print("Welcome to Dashboard")
user = {"name": "John", "is_logged_in": True}
view_dashboard(user)
Multiple Decorators
You can apply more than one decorator:
@decorator_one
@decorator_two
def my_function():
pass
Execution order is bottom to top:
decorator_two → decorator_one → function
Class-Based Decorators
Decorators can also be written using classes.
class DecoratorClass:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Before execution")
return self.func(*args, **kwargs)
@DecoratorClass
def greet():
print("Hello!")
greet()
Common Use Cases in Real Projects
Decorators are heavily used in:
- Web frameworks (authentication, routing)
- API request logging
- Caching results
- Timing functions
- Input validation
Summary
Python decorators are an advanced but very useful feature that helps you:
- Extend functions without modifying them
- Write cleaner and reusable code
- Implement cross-cutting concerns like logging and security
Once mastered, decorators make your Python code more powerful and professional.
Conclusion
Decorators are one of the most elegant features of Python. They allow developers to enhance functions dynamically and are widely used in real-world applications.
If you are building web apps or APIs using Python, understanding decorators is essential for writing scalable and maintainable code.


0 Comments