~2 min read • Updated Sep 16, 2025
Introduction
Decorators in Python are one of the most elegant features for managing and enhancing the behavior of functions and classes. They allow you to wrap additional logic around existing code without modifying its internal structure. This makes your code cleaner, more modular, and easier to maintain.
Basic Structure of a Decorator
A decorator is a function that takes another function as input and returns a modified version of it:
def my_decorator(func):
def wrapper():
print("Before function runs")
func()
print("After function runs")
return wrapperUsing the @ Symbol
To apply a decorator to a function, use the @ symbol:
@my_decorator
def say_hello():
print("Hello!")say_hello()Output:
Before function runs
Hello!
After function runsDecorators with Arguments
To support functions with arguments, use *args and **kwargs:
def log_decorator(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args} and {kwargs}")
return func(*args, **kwargs)
return wrapperCommon Use Cases
- Logging: Track function calls and parameters
- Authentication: Check user access before executing a function
- Caching: Store results to avoid repeated computation
- Timing: Measure execution time of functions
Built-in Python Decorators
Python provides several built-in decorators:
@staticmethodfor defining static methods@classmethodfor methods that access the class itself@propertyto turn a method into a readable attribute
Nested Decorators
You can apply multiple decorators to a single function:
@auth_check
@log_decorator
def process_data():
passIn this case, log_decorator runs first, followed by auth_check.
Conclusion
Decorators in Python are a powerful way to enhance and control function behavior. They help you implement shared logic in a clean, reusable manner. Mastering decorators is a key step toward writing professional, scalable Python code.
Written & researched by Dr. Shahin Siami