Did you put sugar in your coffee today? Let’s introduce the concept and use of decorators with a simple example. Before we introduce decorators, let’s look at the concept of functions. 1. In Python, functions are first-class citizens, and functions are also objects. We can assign a function to a variable.
Def make_cofe(type): print(' get a cup of: {}'.format(type)) get_cofe = make_cofe get_cofe(' coffee ') #### output ##### get a cup of: coffeeCopy the code
In this example, we assign the function make_cofe to the variable get_cofe, so that when you call get_cofe afterwards, you are calling make_cofe(). 2. Pass this function as an argument to another function.
Def make_cofe(type): print(' get a cup: {}'.format(type)) def shop(func,type): Func (type) the shop (make_cofe, 'coffee') # # # # # # # # output for a cup of: coffeeCopy the code
In this example, we pass the make_cofe as a parameter to shop and then call it. Functions can be nested.
Def shop(type): def make_cofe(type): print(' get a cup of: {}'.format(type)) make_cofe(type) shop(' coffee ') ##### output #### get a cup of: coffeeCopy the code
In this code, we define the function make_cofe inside the function shop. 4. The return value of the function can also be a function object (closure).
Def shop(): def make_cofe(type): print(' get a cup: {} '. The format (type)) return make_cofe get_cofe = shop () get_cofe (" coffee ") # # # # # # # # # output for a cup of: coffeeCopy the code
Here, the function shop() returns the function object make_cofe itself, which we then assign to the variable get_cofe and call get_cofe(” coffee “). Next, we officially began to study decorators. Let’s start with a question. If we go to the coffee shop and ask for a cup of coffee, how should we achieve it. You might write something like this.
Def cofe () : print (' coffee 'end =' ') cofe () # # # # # # # # output of coffeeCopy the code
So now we want a cup of coffee with sugar, how should we write? You might think, well, that’s not easy, just change it in the cofe() function.
Def cofe () : print (' coffee with sugar, end = ' ') cofe () output # # # # # # # # coffee with sugarCopy the code
So the question is, what do we do if we don’t want to drink coffee with sugar now, because we can’t get rid of the cofe() function. So what if some people want to have coffee with sugar and some people don’t want coffee with sugar, you can’t write two coFe () functions. So let’s look at the following code with the problem in mind.
Def add_sugar(func): def add(): print(' add sugar ',end= ") func() return add def cofe(): Print (' coffee 'end =' ') cofe = add_sugar (cofe) print (" get a cup of ", end = ' ') cofe () output # # # # # # # # # get a cup of coffee with sugarCopy the code
The variable cofe refers to the inner function add(), which in turn calls the original function cofe(), so the final call to cofe() will print ‘sugar’ and then ‘coffee’. The function add_sugar() is a decorator that wraps around the actual function, cofe(), and changes its behavior without changing the original function, cofe(). Now let’s write it a little bit more elegantly.
Def add(): def add(): print(' add sugar ',end= ") func() return add @add_sugar def cofe(): Print (' coffee 'end =' ') print (" get a cup of ", end = ' ') cofe () output # # # # # # # # # # get a cup of coffee with sugarCopy the code
@add_sugar is just like the previous coFE = add_sugar(cofe) statement, only more concise. This is why it is recommended in the program. Ok, so let’s review our question, what happens if some people want to drink coffee with sugar and some people don’t. If you want to drink coffee with sugar, we will add the “@add_sugar” with sugar. If you drink coffee without sugar, you will not add the “add_sugar”. So we have solved the problem perfectly. Add new functionality to the function without changing the inside of the function. So far, we’ve gone through the simplest decorator. Let’s consider the following question: what if the original function cofe() has arguments that need to be passed to the decorator? An easy way to do this is to add an argument to the corresponding decorator function add().
Def add(type): print(' add sugar ',end='') func(type) return add @add_sugar def cofe(type): Print (' {} 'coffee. The format (type), end =' ') cofe (" American ") print () cofe (" latte ") # # # # # # # # # output american-style coffee with sugar Sugar latteCopy the code
But here comes a new problem. What if I have another function (the milk tea function) that also needs to use the add_sugar() decorator, but this new function takes two arguments? Normally, we would use *args and **kwargs as arguments to the add() function inside the decorator. *args and **kwargs mean to accept any number and type of arguments, so the sugar decorator can be written like this:
def add_sugar(func): def add(*args, **kwargs): Print (' add sugar ',end='') func(*args, **kwargs) return add @add_sugar def cofe(type): Print ('{} coffee '.format(type),end= ") @add_sugar def milk_tea(type,num): Print (' {} {} cup milk tea. The format (num, type), end = ' ') cofe (" American ") print () milk_tea (" xx brand ", "4") # # # # # # # # output american-style coffee with sugar sugar 4 cups of xx brand milk teaCopy the code
So we can add sugar to both our coffee and milk tea. So far we’ve talked about function decorators. Now let’s talk about classes as decorators. The class decorator relies primarily on the function __call__(), which is executed every time you call an instance of the class.
Class Add_sugar: def __call__(self, *args, **kwargs): self. print(self.add_suger,end='') return self.func(*args, **kwargs) @Add_sugar def cofe(): Print (" coffee ") cofe() #### output ##### sweetened coffeeCopy the code
Finally, if we want our coffee with both sugar and ice, how do we make it? Let’s just define a decorator with ice.
Def add_sugar(func): def add(): print(' add sugar ',end='') func() return add def add_ice(func): def add(): Print (' ice 'end =' ') func () return the add @ add_sugar @ add_ice def cofe () : print (' coffee 'end =' ') cofe () # # # # # # # # output ice coffee with sugarCopy the code
From then on, we could add whatever we wanted to our coffee. Welcome to leave a message and communicate with me. For more interesting content, get more learning materials
Please follow the public account ‘Lao Han essay’ and reply to ‘data’.