Mastering Python Decorators: A Deep Dive

1. Introduction to Decorators
Python decorators are a powerful way to modify or enhance functions and methods without changing their code. They follow the higher-order function concept, allowing functions to be passed as arguments and returned from other functions.
Basic Example
pythondef decorator_function(original_function):
def wrapper_function():
print(f"Executing {original_function.__name__}")
return original_function()
return wrapper_function@decorator_function
def say_hello():
print("Hello, World!")
say_hello()
🔹 Output:
nginxExecuting say_hello
Hello, World!💡 @decorator_function is syntactic sugar for say_hello = decorator_function(say_hello).
2. Understanding Function Decorators
Decorators with Arguments
pythondef repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
func(*args, **kwargs)
return wrapper
return decorator@repeat(3)
def greet():
print("Hello!")
greet()
🔹 Output:
Hello!
Hello!
Hello!💡 The decorator takes arguments (n), modifying how the function behaves dynamically.
3. Using functools.wraps to Preserve Metadata
Using functools.wraps ensures that the decorated function retains its original metadata (name, docstring).
pythonimport functoolsdef decorator_function(original_function):
@functools.wraps(original_function)
def wrapper_function(*args, **kwargs):
print(f"Executing {original_function.__name__}")
return original_function(*args, **kwargs)
return wrapper_function
@decorator_function
def example():
"""This is an example function."""
print("Example function executed!")
print(example.__name__) # Retains 'example' instead of 'wrapper_function'
print(example.__doc__) # Displays the function's docstring
4. Chaining Multiple Decorators
You can apply multiple decorators to a function:
pythondef uppercase(func):
def wrapper():
return func().upper()
return wrapperdef exclaim(func):
def wrapper():
return func() + "!!!"
return wrapper
@uppercase
@exclaim
def greet():
return "hello"
print(greet()) # Output: HELLO!!!
💡 Execution order: exclaim → uppercase → greet().
5. Class-Based Decorators
Instead of functions, decorators can also be implemented as classes with __call__.
pythonclass Logger:
def __init__(self, func):
self.func = funcdef __call__(self, *args, **kwargs):
print(f"Logging: {self.func.__name__} called with {args}")
return self.func(*args, **kwargs)
@Logger
def add(a, b):
return a + b
print(add(3, 5)) # Output: Logging: add called with (3, 5)
💡 Useful for stateful decorators that maintain persistent data.
6. Real-World Use Cases
a) Logging Function Calls
pythonCopyEditimport timedef log_time(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} took {end - start:.2f}s")
return result
return wrapper
@log_time
def process_data():
time.sleep(2)
print("Data processed!")
process_data()
💡 Use Case: Performance monitoring.
b) Access Control (Authentication Decorator)
pythondef requires_auth(role):
def decorator(func):
def wrapper(*args, **kwargs):
user_role = "admin" # Example user role
if user_role != role:
print("Access denied!")
return
return func(*args, **kwargs)
return wrapper
return decorator@requires_auth("admin")
def sensitive_function():
print("Sensitive operation performed!")sensitive_function()
💡 Use Case: API authentication.
c) Caching Expensive Function Calls
pythonimport functoolsdef cache(func):
cache_data = {}
@functools.wraps(func)
def wrapper(*args):
if args in cache_data:
print("Fetching from cache...")
return cache_data[args]
result = func(*args)
cache_data[args] = result
return result
return wrapper
@cache
def expensive_calculation(x):
print("Performing expensive calculation...")
return x * x
print(expensive_calculation(4)) # Performs calculation
print(expensive_calculation(4)) # Fetches from cache
💡 Use Case: Optimizing API calls, database queries, or expensive calculations.
Conclusion
Python decorators provide a powerful way to modify functions dynamically while keeping code clean and modular. From simple function wrappers to advanced logging, caching, and authentication, decorators are an essential tool in every Python developer’s toolkit.
WEBSITE: https://www.ficusoft.in/python-training-in-chennai/
Comments
Post a Comment