In Python, decorators provide a simple and effective way to modify the behavior of functions or methods. They are particularly useful in various real-world applications, such as logging, access control, and caching. This article explores two common practical use cases of decorators: Logging and Access Control.
A logging decorator is used to automatically log information about function calls, such as the function name, arguments, and result. This can help track the flow of a program and is particularly useful for debugging and monitoring.
import functools def log_function_call(func): @functools.wraps(func) def wrapper(*args, **kwargs): print(f"Function '{func.__name__}' called with arguments {args} and keyword arguments {kwargs}") result = func(*args, **kwargs) print(f"Function '{func.__name__}' returned {result}") return result return wrapper @log_function_call def add(a, b): return a + b @log_function_call def multiply(a, b): return a * b # Testing the decorator add(2, 3) multiply(4, 5)
In this example, we created a decorator log_function_call
that logs the function name, arguments, and result. The decorator is applied to two functions, add
and multiply
, which perform basic arithmetic operations.
Function 'add' called with arguments (2, 3) and keyword arguments {} Function 'add' returned 5 Function 'multiply' called with arguments (4, 5) and keyword arguments {} Function 'multiply' returned 20
The logging decorator helps to easily track and monitor the behavior of functions by automatically logging each call.
Access control decorators are used to restrict access to certain functions or methods based on conditions such as user permissions or roles. This is commonly used in web applications for controlling access to specific pages or API endpoints based on user authentication or authorization.
def requires_permission(permission): def decorator(func): def wrapper(user, *args, **kwargs): if permission not in user.permissions: raise PermissionError(f"User does not have '{permission}' permission.") return func(user, *args, **kwargs) return wrapper return decorator class User: def __init__(self, name, permissions): self.name = name self.permissions = permissions @requires_permission("admin") def view_admin_dashboard(user): print(f"Welcome {user.name}, you are viewing the admin dashboard.") # Creating users with different permissions user1 = User("Alice", ["admin", "user"]) user2 = User("Bob", ["user"]) # Testing access control view_admin_dashboard(user1) # Alice has admin permission view_admin_dashboard(user2) # Bob does not have admin permission
In this example, we created a decorator requires_permission
that checks whether a user has the required permission before executing the decorated function. The function view_admin_dashboard
is protected by this decorator, so only users with the "admin" permission can access it.
Welcome Alice, you are viewing the admin dashboard. PermissionError: User does not have 'admin' permission.
As shown, the access control decorator ensures that only users with the correct permissions can execute certain functions, which helps enforce security and access restrictions in applications.
Decorators in Python provide a powerful and flexible way to modify the behavior of functions and methods. In this article, we explored two practical use cases of decorators: logging and access control. The logging decorator helps track function calls, while the access control decorator ensures that only authorized users can perform certain actions. Both use cases demonstrate the versatility of decorators in solving common problems efficiently and cleanly.