Python Decorators
Python decorators are a powerful feature that allows you to modify or extend the behavior of functions and methods without changing their original code. They are commonly used when additional functionality needs to be added to an existing function in a clean and reusable way.
Decorators are closely related to higher-order functions, inner functions, and Python’s ability to treat functions as first-class objects. In this guide, we will understand these concepts and explore practical decorator examples.
Table of Contents

What Are Decorators?
A decorator is a function that receives another function as an argument and returns a new function with additional or modified behavior.
In simple terms, a decorator allows you to add functionality to an existing function without directly modifying its implementation. Decorators are a form of metaprogramming because they can modify program behavior at runtime.
Understanding the Basics
Before learning decorators, it is useful to understand three important Python concepts: functions as first-class objects, inner functions, and higher-order functions.
Functions as First-Class Objects
Python treats functions as first-class objects. This means functions can be assigned to variables, passed as arguments, and returned from other functions.
def greet(message):
print(message)
# Assign function to another variable
hello = greet
hello("Hello, World!")
Output:
Hello, World!
Inner Functions
An inner function is a function defined inside another function. Inner functions are frequently used when creating decorators.
def outer_function():
print("This is the outer function.")
def inner_function():
print("This is the inner function.")
inner_function()
outer_function()
Output:
This is the outer function.
This is the inner function.
Higher-Order Functions
A higher-order function either accepts another function as an argument or returns a function as its result.
def increment(x):
return x + 1
def apply_function(func, value):
return func(value)
result = apply_function(increment, 5)
print(result)
Output:
6
What Is a Decorator?
A decorator is essentially a higher-order function that takes a function, adds functionality around it, and returns the enhanced function.
Here is a simple decorator example:
def decorator(func):
def wrapper():
print("Before the function call")
func()
print("After the function call")
return wrapper
@decorator
def say_hello():
print("Hello!")
say_hello()
Output:
Before the function call
Hello!
After the function call
The @decorator syntax is a convenient way of applying a decorator. The following statement represents the same operation:
say_hello = decorator(say_hello)
Decorators with Parameters
Decorators can also be designed to accept parameters. This requires an additional function layer that receives the decorator’s arguments.
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
Output:
Hello, Alice!
Hello, Alice!
Hello, Alice!
Common Use Cases for Decorators
1. Logging
Decorators can be used to display information about function calls, their arguments, and their returned results.
def log(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with arguments {args} and {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result}")
return result
return wrapper
@log
def add(a, b):
return a + b
add(5, 3)
Output:
Calling add with arguments (5, 3) and {}
add returned 8
2. Authentication
A decorator can also be used to check whether a user has permission to access a particular function.
def requires_auth(func):
def wrapper(user):
if user.get("authenticated"):
return func(user)
else:
print("Authentication required!")
return wrapper
@requires_auth
def view_profile(user):
print(f"Welcome, {user['name']}!")
user = {
"name": "Alice",
"authenticated": True
}
view_profile(user)
Output:
Welcome, Alice!
3. Measuring Execution Time
Decorators can measure how long a function takes to execute.
import time
def timing(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(
f"{func.__name__} executed in "
f"{end_time - start_time:.4f} seconds"
)
return result
return wrapper
@timing
def compute():
time.sleep(2)
print("Computation complete!")
compute()
Output:
Computation complete!
compute executed in 2.0001 seconds
Advanced Decorators
Complete Advance AI Topics: Click Here
SQL Tutorial: Click Here
YT:- DecodeIT
1. Class Decorators
A class that implements the __call__() method can be used as a decorator.
class Decorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Before the function call")
result = self.func(*args, **kwargs)
print("After the function call")
return result
@Decorator
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
Output:
Before the function call
Hello, Alice!
After the function call
2. Nesting Decorators
Python allows multiple decorators to be applied to the same function by stacking them.
def uppercase(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result.upper()
return wrapper
def exclaim(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result + "!"
return wrapper
@uppercase
@exclaim
def greet(name):
return f"Hello, {name}"
print(greet("Alice"))
Output:
HELLO, ALICE!
Frequently Asked Questions
1. What is a decorator in Python?
A decorator is a function that receives another function and returns an enhanced version of that function.
2. Why are decorators used in Python?
Decorators are used to add functionality to existing functions without changing their original implementation.
3. What does the @ symbol mean in Python decorators?
The @ syntax provides a concise way to apply a decorator to a function.
4. Can decorators accept arguments?
Yes. Decorators can be designed to accept arguments by adding another function layer.
5. Can a class be used as a decorator?
Yes. A class can work as a decorator when it implements the __call__() method.
6. Can multiple decorators be applied to one function?
Yes. Multiple decorators can be stacked above a function, allowing several behaviors to be applied.
Conclusion
Python decorators provide a flexible way to extend and modify function behavior without changing the original function code. They are built around important Python concepts such as first-class functions, inner functions, and higher-order functions.
From logging and authentication to execution-time measurement, class decorators, and nested decorators, this feature provides a reusable approach for adding functionality to Python programs.
Keywords: Python Decorators, python decorator, python decorators with arguments, decorators in Python example, types of decorators in Python, python class decorator, python decorators for class methods, decorator function in Python, Python decorator tutorial, Python decorators W3Schools