Python Decorators
Decorators in Python are an advanced feature that allows you to dynamically modify the behavior of functions or classes.
A decorator is essentially a function that takes another function as its argument and returns a new function or modifies the original one.
The syntax for using decorators involves the @decorator_name placed before the function or method you want to decorate.
Python also provides built-in decorators such as @staticmethod and @classmethod, which are used to define static methods and class methods, respectively.
Use Cases of Decorators:
Logging: Decorators can be used to log information about function calls, arguments, and return values.
Performance Analysis: They can measure the execution time of a function.
Access Control: Decorators can restrict access to certain functions.
Caching: They can implement caching of function results to improve performance.
Basic Syntax
In Python, decorators allow you to dynamically add or modify functionality to functions without altering their code. Essentially, a decorator is a function that takes another function as input and returns a modified version of it.
Syntax Example
def decorator_function(original_function): def wrapper(*args, **kwargs): # Code before calling the original function before_call_code() result = original_function(*args, **kwargs) # Code after calling the original function after_call_code() return result return wrapper
Using a Decorator
@decorator_function def target_function(arg1, arg2): pass # Original function implementation
Explanation:
decorator_functionis a decorator that takesoriginal_functionas an argument.wrapperis an inner function that is called instead of the original function, allowing you to add extra behavior before and after the original function call.When you apply
@decorator_functiontotarget_function, Python automatically passestarget_functiontodecorator_functionand replaces the original function with thewrapper.
Using a Decorator
Decorators are applied by placing the @ symbol before the function definition, like this:
@time_logger def target_function(): pass
This is equivalent to:
def target_function(): pass target_function = time_logger(target_function)
This passes the target_function to the time_logger decorator, which returns a new function, assigning it back to target_function. Thus, whenever target_function is called, the decorated version of the function is executed.
Decorators allow developers to extend the functionality of their programs efficiently while maintaining clean code.
Parameterized Decorators
Decorators can also accept arguments, allowing for even greater flexibility.
Example
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")In this code, the repeat function is a parameterized decorator that takes an integer n. It returns a decorator that repeats the execution of the original function n times. When greet is decorated with @repeat(3), it prints the greeting three times.
Class Decorators
In addition to function decorators, Python also supports class decorators. A class decorator is a class that implements the __call__ method. It takes a function as its argument and returns a modified version of that function.
Example
class DecoratorClass: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): # Code before the original function is called result = self.func(*args, **kwargs) # Code after the original function is called return result @DecoratorClass def my_function(): pass
In this example, DecoratorClass acts as a decorator. When @DecoratorClass is applied to my_function, the __call__ method of DecoratorClass is invoked each time my_function is called.