Python Decorators
A decorator in Python is a design pattern that allows you to add new functionality to an existing object without modifying its structure. Decorators are usually called before the definition of a function you want to decorate.
In this tutorial, you’ll learn about the basics of decorators and how to create your own.
Understanding Decorators
A decorator is a function that takes another function as an argument, adds some kind of functionality, and then returns another function.
Here’s a simple example of a decorator:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()When you run this code, you’ll see the following output:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.The @my_decorator syntax is just a shorter way of saying say_hello = my_decorator(say_hello).
Creating Your Own Decorators
To create a decorator, you just need to define a function that takes a function as an argument and returns another function.
Here’s an example of a decorator that logs the execution time of a function:
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} took {end_time - start_time:.4f} seconds to run.")
return result
return wrapper
@timer
def my_function(n):
sum = 0
for i in range(n):
sum += i
return sum
my_function(1000000)In this example, the timer decorator takes a function as an argument and returns a wrapper function. The wrapper function records the start time, calls the original function, records the end time, and then prints the execution time.
The *args and **kwargs in the wrapper function are used to pass any arguments to the original function.
Decorators with Arguments
You can also create decorators that take arguments. Here’s an example of a decorator that repeats a function a certain number of times:
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 say_hello():
print("Hello!")
say_hello()This will print “Hello!” three times.
Common Use Cases for Decorators
Decorators are used for a variety of purposes in Python, including:
- Logging: Logging the execution of a function.
- Timing: Timing how long a function takes to run.
- Caching: Caching the results of a function to improve performance.
- Authentication: Checking if a user is authenticated before allowing them to access a function.
- Validation: Validating the arguments of a function.
Conclusion
In this tutorial, you’ve learned about Python decorators and how to create your own. Decorators are a powerful tool that can help you to write more concise and reusable code.
For more information on decorators, you can refer to the official Python documentation: https://www.python.org/dev/peps/pep-0318/