Python Decorators
Python decorators are a powerful tool for modifying or extending the behavior of functions or methods without directly modifying their code. They are commonly used for tasks like logging, enforcing access control, memoization, timing, or modifying function arguments.
What are Decorators ?
A decorator is a function that takes another function as an argument and returns a new function (or a modified version of the original). This is achieved using Python's syntactic sugar with the @decorator_name notation.
def decorator_function(original_function): def wrapper_function(*args, **kwargs): print(f"Wrapper executed before {original_function.__name__}") return original_function(*args, **kwargs) return wrapper_function @decorator_function def display(): print("Display function ran") display()
Output
Wrapper executed before display Display function ran
Examples of Python Decorators
1) Logging
A logging decorator in Python is a tool that adds logging functionality to functions without changing the core logic of the functions. This can make code easier to debug, maintain, and more modular
def logger(func): def wrapper(*args, **kwargs): print(f"Function {func.__name__} called with {args} {kwargs}") return func(*args, **kwargs) return wrapper @logger def add(a, b): return a + b print(add(3, 5))
Output
Function add called with (3, 5) {} 8
2) Access Control
An access control decorator is a tool that checks if a user has the required permissions before executing a function.
def requires_admin(func): def wrapper(user, *args, **kwargs): if not user.get("is_admin"): raise PermissionError("User is not an admin") return func(user, *args, **kwargs) return wrapper @requires_admin def delete_user(user, user_id): print(f"User {user_id} deleted by {user['username']}") admin_user = {"username": "admin", "is_admin": True} regular_user = {"username": "guest", "is_admin": False} delete_user(admin_user, 42) # delete_user(regular_user, 42) # Raises PermissionError
Output
User 42 deleted by admin
3) Class Decorators
A Python class decorator adds a class to a function, and it can be achieved without modifying the source code
def uppercase_decorator(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) return result.upper() return wrapper class Greeter: @uppercase_decorator def greet(self, name): return f"Hello, {name}" g = Greeter() print(g.greet("world"))
Output
HELLO, WORLD