The Python decorator is a high-frequency question asked during the interview process, and the adorner is a very useful feature,
Mastering the decorator will make your programming ideas wider and the program more pythonic.
Today we combine the latest World Cup with the next one to understand the decorator.
German chariot
June 17 German war in Mexico, although the little crazy is a pseudo-fan, but the annual World Cup will still understand. And Germany is the last title, and this is a popular title. The German chariot has not lost in the 32-year group game! Lying trough! Although little silly gambling, but this time Germany is so strong, will certainly win it. Beat a bike to become a motorcycle! Then the little fetish bought the German team to win. I think this time is sure to stabilize! Win the Clubhouse tender mold! Little fool even look at the game, flattered to knock the code.
Then the result is the German upset 0:1 lost to Mexico, Germany lost the game, little Crazy also work in the sea. But the roof is a little crowded at this time, the wind is still big.
The little crazy tearful wrote down the following code:
def guess_win(func): def rooftop_status(): result = func() print(‘天台已满,请排队!‘) return result return rooftop_status@guess_windef german_team():
Output Result:
德国必胜! 天台已满,请排队! 复制代码
What is an adorner?
First we first understand what is the adorner, strictly speaking, the adorner is only a syntactic sugar, the adorner is callable object, can be called like a regular callable object, the special place is the adorner parameter is a function.
Adorners exist for two scenarios, one is to enhance the behavior of the decorated function, and the other is code reuse.
For example in the above example we in the German team to win, the original German_team () function is only output Germany to win, but after using the adorner (Guess_win), it has more than one function: Output "Rooftop is full, please queue!" 」。 This is a simple adorner that implements the "enhanced behavior of the decorated function".
A good adorner must adhere to the two principles:
It is not difficult to understand that in today's production environment, a lot of code is not easy to rewrite, because it is possible to send unexpected effects. Another thing is that we are looking at the code of the Great God, and we simply don't know how to rewrite it. At the same time you cannot modify the invocation mode because you do not know how many of these functions have been applied in a project.
The adorner understands the basics
If you want a good understanding of the adorner, the following two things need to be recognized first.
1 function names can be assigned to variables
Let's look at this example:
def func(name):
Output Result:
我是梅西!慌的一逼! 我是勒夫!慌的一逼!
In the code we first define the function func, and call the Func function, and assign the Func to Y. Y = func indicates that the function name can be assigned to a variable and does not affect the invocation.
That said, there may be some people who don't understand. We are here to compare our usual operations. This is actually the same as the integer, the number is the same, the following code you must be familiar with:
2 Higher order functions
The higher order function satisfies any of the following two conditions: A. You can receive a function name as an argument; b. The return value can contain the function names.
Functions such as map and filter in the Python standard library are higher-order functions.
l = [1, 2, 4]r = map(lambda x: x*3, l)for i in r:
Output Result:
当前天台人数: 3 当前天台人数: 6 当前天台人数: 12 复制代码
Customizing a function that can return functions is also a higher-order function:
def f(l): return map(lambda x: x *5, l)a = f(l)for i in a: print(‘当前天台人数:‘, i)
Output Result:
当前天台人数: 5 当前天台人数: 10 当前天台人数: 20 复制代码
Implement a similar adorner
Now that you know the function name assignment and the higher order function, with these two foundations, we can try to implement a similar adorner.
def status(func): print(‘慌的一逼!‘) return funcdef name():
Output Result:
慌的一逼! 我是梅西!
In this example we define a status function that receives a function name and returns the function name directly. This allows us to implement the requirement of not modifying the original function name and adding a new feature. But there is a flaw in the way that the function's invocation has changed. This is not the original name, but the temp.
To solve this problem is very simple, I believe that a = a*3 expression such as everyone has seen, then the above code, the TEMP = status can also be modified to name = status (name), so that we have a perfect solution to the problem: the addition of new features and not modify the original function and its Call mode. The modified code is as follows:
def status(func): print(‘慌的一逼!‘) return funcdef name():
But there is a disadvantage to this code, which is that each time we use such an adorner, we write code similar to name = status (name). Programmers are lazy, so there are so many advanced grammars. In Python in order to simplify this situation, provided a syntax sugar @, on each decorated function above the use of this syntax sugar can be omitted this code name = status (name), the final code is as follows:
def status(func): print(‘慌的一逼!‘) return func@statusdef name():
So we can figure out how the decorator works:
1 Write a high-order function, that is, the parameter is a function, return is also a function.
2 Use the syntax sugar @ To simplify the assignment operation.
But there are some different examples from the beginning of the comparison. In the first example, we also implemented a Rooftop_status function to determine if the current rooftop is full. But now we're returning the function name directly, so we can't do anything after the function call. Lionel Messi and Germany panic, we also panic, all have to see the rooftop, but before this we also have to consider the situation of the rooftop.
In order to be able to judge the roof, we need to nest a layer of functions, the implementation of the additional functions of the part is written in the inner function, and then return the inner layer function. This is why adorners are nested functions.
In addition, the opening example does not have a return value, and there are no parameters, to decorate the function that has both parameters and return values, it needs to be further perfected. Adorners capable of handling return values:
def guess_win(func): def rooftop_status(): result = func() print(‘天台已满,请排队!‘) return result return rooftop_status@guess_windef german_team(): print(‘德国必胜!‘)
Output Result:
德国必胜! 天台已满,请排队! 赢了会所嫩模!输了下海干活!
adorners capable of handling parameters:
def guess_win(func): def rooftop_status(*args, **kwargs): result = func(*args, **kwargs) print(‘天台已满,请排队!‘) return result return rooftop_status@guess_windef german_team(arg): print(‘{}必胜!‘.format(arg))
Output Result:
德国必胜! 天台已满,请排队! 西班牙必胜! 天台已满,请排队! 赢了会所嫩模!输了下海干活!
Summarize
The essence of an adorner is a function whose argument is another function (the decorated function). The adorner usually handles the decorated function extra, then returns it, or replaces it with another function or callable object. A well-behaved adorner can be reused to reduce the amount of code.
For this World Cup, I summed up the next. Don't say, the roof is waiting for me.
More wonderful articles will be in the public number:Coxie you learn programming publishing
Welcome to Subscribe
Use the World Cup to read Python decorators