Python Decorators: A Comprehensive Guide
Python Decorators
Python decorators are a special and potent tool that let you change or expand the behavior of methods or functions. This guide will explore decorators, their significance, and how they work, with examples to help you understand their practical applications.
What are Decorators?
A decorator is a function that returns a new function with improved or altered behavior after receiving another function as an input. They enable you to dynamically change a function’s behavior without altering its actual code.
In essence, decorators are a form of metaprogramming — allowing a part of the program to modify another part at runtime.
Understanding the Basics
Before diving into decorators, let’s clarify some foundational concepts in Python:
Functions as First-Class Objects
In Python, functions are treated as first-class objects. This means they can:
- Be assigned to variables.
- Be passed as arguments to other functions.
- Be returned from other functions.
Example:
def greet(message):
print(message)
# Assign function to another variable
hello = greet
hello("Hello, World!")
Output:
Hello, World!
Download New Real Time Projects :-Click here
Inner Functions
Python allows you to define functions inside other functions, known as inner functions. These are often used in decorators.
Example:
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
Higher-order functions are those that return a function or accept another function as an argument.
Example:
def increment(x):
return x + 1
def apply_function(func, value):
return func(value)
result = apply_function(increment, 5)
print(result)
Output:
6
PHP PROJECT:-Â CLICK HERE
What is a Decorator?
In essence, a decorator is a higher-order function that:
- Takes a function as input.
- Adds some functionality to it.
- Returns the enhanced function.
Here’s a simple decorator in action:
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
For the following, the @decorator syntax is syntactic sugar:
say_hello = decorator(say_hello)
Decorators with Parameters
Additionally, decorators are more adaptable because they can take disagreements. To achieve this, you need to create an additional layer of functions.
Example:
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
Function calls and their outputs are frequently logged using decorators.
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
Decorators can enforce access control.
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 track 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 {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
1. Class Decorators
Classes that define the call method can be used as decorators.
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
A function can have more than one decorator stacked on it.
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!
- python decorators w3schools
- Python Decorators: A Comprehensive Guide
- Python Decorators
- 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
- generators in python
- python decorator
- python interview questions
Post Comment