In this tutorial, we will learn about the concept of decorators in Python and how to call them. Decorators provide a simple and readable way to modify the behavior of functions or classes in Python. With the use of decorators, you can wrap your functions or classes with other functions to add additional functionalities.
Step 1: Understand how Decorators work
A decorator is a callable Python object that accepts a function or class as an argument and returns a modified version of the same function or class with some additional properties or behavior.
Here’s an example of a simple decorator function:
1 2 3 4 5 6 7 8 9 10 11 12 |
def simple_decorator(fn): def wrapper(): print("Before the function call") fn() print("After the function call") return wrapper def hello_world(): print("Hello World!") decorated_hello_world = simple_decorator(hello_world) decorated_hello_world() |
In this example, we’ve created a simple_decorator
that takes a function fn
as an argument, and inside the decorator, we’ve added a wrapper
function that prints a message before and after the fn
function call. We then use this decorator to create a decorated_hello_world
function and call it. The output would look like this:
Before the function call Hello World! After the function call
Step 2: Call Decorators using the @ symbol
To make it easier to apply decorators in Python, you can use the @decorator_name syntax. It is a syntactic sugar to make the code more readable and less verbose.
In the previous example, applying the decorator can be rewritten using the @ symbol as follows:
1 2 3 4 5 |
@simple_decorator def hello_world(): print("Hello World!") hello_world() |
This syntax automatically wraps the hello_world()
function with the simple_decorator
and provides the same output as in the previous example.
Step 3: Define Decorators with Arguments
You can also create decorators that accept arguments. To achieve this, you need to create another function layer in your decorator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def greeting_decorator(prefix): def inner_decorator(fn): def wrapper(): print(f"{prefix} - Before the function call") fn() print(f"{prefix} - After the function call") return wrapper return inner_decorator @greeting_decorator("Hello") def hello_world(): print("Hello World!") hello_world() |
In this example, the greeting_decorator
accepts a prefix
argument and uses it in the wrapper
function. We apply the decorator with the argument using the @decorator_name(argument)
syntax.
The output of this code would be:
Hello - Before the function call Hello World! Hello - After the function call
Full Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
def simple_decorator(fn): def wrapper(): print("Before the function call") fn() print("After the function call") return wrapper @simple_decorator def hello_world(): print("Hello World!") hello_world() def greeting_decorator(prefix): def inner_decorator(fn): def wrapper(): print(f"{prefix} - Before the function call") fn() print(f"{prefix} - After the function call") return wrapper return inner_decorator @greeting_decorator("Hello") def hello_world(): print("Hello World!") hello_world() |
Conclusion
In this tutorial, we have learned about decorators in Python, how to call them using the @ symbol, and how to define decorators with arguments. Decorators are a powerful and versatile feature in Python that allows you to modify the behavior of functions and classes in a clean and efficient manner.