One of the advantages of a decorator in Python is that it can make the usage of function be extended, but no need to modify the original functions.
Today let’s take an example to check it step by step.
Let’s say I have defined a lot of original functions as below:
The problem: After serval months, I want to print some words to all of the calculation functions (add, minus, and multiply) before and after the calculation to make the process more clear. What should I do?
Method1: Change the original functions: add the printed words to the original functions:
It does work, but isn’t it too redundant? And this method changes the original codes, is it what I expect? No, it isn’t.
Now how to realize this function without making any change to the original function? Let’s try method 2.
Method2: use the nested function:
This method has to define the function add() inside the new_func(). Let’s run it:
It works. The nested function extends the function of add without making any changes on add, but, the nested function is fixed as add(), how about the other functions, like minus, and multiply? It isn’t flexible and still has to rewrite all of the functions, not what I expect. Let’s try method 3.
Method 3: Add one more nested function and use the variable func to transfer the function I want to calculate.
Compared with 2, no need to fix the nested function. It is much more flexible. We can transfer different functions to new_func_func().
If the nested function is add(), the result is as :
Good, it works for the functions of add, minus, multiple, and divide, which need two variables but doesn’t work for function f_print, as f_print doesn’t need to transfer any variables.
What I should do? Let’s check method 4.
Method 4: Use *args and **kwargs, when we are not sure whether there are arguments and what the arguments are :
- *args is arbitrary positional arguments, **kwargs is arbitrary keyword arguments.
Let’s check the result:
Perfect! This function works for both cases: the function with parameters or without parameters and it has great flexibility.
Now, we have already created and used a decorator, but there is another way to use it, which is also much more popular.
Method5: use ‘@decorator_name’
Take multiply function as an example:
From these steps, we can see that the decorator extends the usage of original functions without modifying them, and it reduces the workload of writing codes.
Hope it helps you to understand Python decorator and thank you for your reading.