Python Decorators

Understanding Python Decorators

Python decorators are a powerful feature that allows you to modify the behavior of a function or a class without changing its source code. They provide a way to add functionality to existing code in a clean and reusable manner. Decorators are implemented using the “@” symbol followed by the name of the decorator function.

How Decorators Work

Decorators in Python are essentially functions that take another function as input and return a new function. They are used to wrap the original function and modify its behavior. This is achieved by defining a new function that calls the original function and adds the desired functionality before or after its execution.

Example: Logging Decorator

Let’s consider an example of a logging decorator that adds logging functionality to a function. The decorator logs the arguments and return value of the function each time it is called.

“`python
def log_decorator(func):
def wrapper(*args, **kwargs):
print(f”Calling function: {func.__name__}”)
print(f”Arguments: {args}, {kwargs}”)
result = func(*args, **kwargs)
print(f”Return value: {result}”)
return result
return wrapper

@log_decorator
def add(a, b):
return a + b

result = add(2, 3)
print(result)
“`

In this example, the `log_decorator` function takes the `add` function as input and returns the `wrapper` function. The `wrapper` function is then assigned to the `add` function using the `@log_decorator` syntax. Now, whenever the `add` function is called, it is actually the `wrapper` function that gets executed.

When we call `add(2, 3)`, the decorator logs the function name, arguments, and return value. The output will be:

“`
Calling function: add
Arguments: (2, 3), {}
Return value: 5
5
“`

Example: Timing Decorator

Another common use case for decorators is to measure the execution time of a function. Let’s take a look at an example of a timing decorator:

“`python
import time

def time_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f”Execution time: {end_time – start_time} seconds”)
return result
return wrapper

@time_decorator
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)

result = fibonacci(10)
print(result)
“`

In this example, the `time_decorator` function measures the execution time of the `fibonacci` function. The decorator calculates the start time before calling the function and the end time after the function has finished execution. It then prints the execution time in seconds.

When we call `fibonacci(10)`, the decorator measures the execution time and prints it. The output will be:

“`
Execution time: 0.000123 seconds
55
“`

Conclusion

Python decorators are a powerful tool for modifying the behavior of functions or classes. They allow you to add functionality to existing code without modifying its source code. Decorators are implemented using the “@” symbol followed by the name of the decorator function. They are widely used for tasks such as logging, timing, caching, and more. By understanding decorators, you can enhance the functionality and flexibility of your Python code.

Scroll to Top