Python decorator, Python decorator, Python decorator, Python decorator, Python decorator.

Decorators, literally, decorate a thing, and what they do in Python is make an existing function have a function that didn’t exist before. A decorator is essentially a function, and its function is to add new functions to other functions.

So some people say, well, I can just add some code to my function, but why do I need a decorator to add functionality? Sure, if you add a function to a function, you can add code, but what if you add the same function to 100 function blocks? Code by code? You’ll break down.

The following is a description of a decorator to implement, to comply with certain rules, is the two unchanged 1. Do not change the decorated function source code 2. Do not change the decorated function call method

The function is called exactly as it is, whether or not you add the decorator

Decorator is also a function, but this function is not the same as ordinary functions, it is a higher order function, so let’s give a general definition of decorator

Decorator: a higher-order function that can add new functionality to other functions (although still not fully defined)

Now let’s talk about higher-order functions.

Higher-order function: A function that can take a function as an argument or reture a function is a higher-order function

Isn’t that a little convoluted? Let me give you an example

def f1():  
    print('Ordinary function')

def f2(func):  The argument to the #f2 function is a function, so it is a higher-order function
    print('Higher order function 1')
    f1()

def f3(func): The return value of the #f3 function is a function, so it is a higher-order function
    print('Higher order function 2')
    returnFunc f2(f1) f3(f1) Result: higher order function 1 Ordinary function higher order function 2Copy the code

For those of you with a little background, this isn’t a decorator at all. It’s a lie. Of course decorators are not that simple.

So the next thing I’m going to introduce is something called a nested function. So what is a nested function? You know what it means, a function has a subfunction inside it

Here’s an example:

def outer():
    print('outer')
    def inner():
        print('inner') inner() outer() outer(Copy the code

Now we’re going to redefine the decorator.

Decorator: a higher-order function + nested function that can add new functionality to other functions

So let’s combine higher-order functions with nested functions

A decorator that can add a line of logs

def add_log(func):  # as a parameter, this function is what we want
    def wrapper():
        print('We're going to add some logs.') # Add a new function to the original function, here is to print a line of log, of course, can implement other complex functions
        func()
    return wrapper

You can see the shadow of higher order function + nested function, which is the simplest decorator pull

@add_log  # The use of decorators
def f1():
    print('Ordinary function')

f1()  # call functionResults:Print (print); print (print); print (print)We are going to add some logging ordinary functionsCopy the code

These decorators probably get the idea.

Now, the top decorator, is there no above problem?

Take a look. Take a look. Can you see that? I can’t tell. I told you.

Our formula 1() function has no arguments, right? Imagine if formula 1() took arguments?

def add_log(func):
    def wrapper(name):
        print('We're going to add some logs.')
        func(name)
    return wrapper

@add_log
def f1(name):
    print('Normal function %s' %name)

f1('python')
Copy the code

Does anyone want to do that?

Of course, this is fine, but let’s not forget that the decorator is not for a fixed function. What if we need to decorate f2(name,age)? No, the decorator code is already set for you, so this is not going to work.

How do I write it?

def add_log(func):
    def wrapper(*args,**kwargs):
        print('We're going to add some logs.')
        func(*args,**kwargs)
    return wrapper

@add_log
def f1(name):
    print('Normal function %s' %name)

@add_log
def f2(name,age):
    print('I am %s and I am %s years old' %(name,age))

f1('python')
f2('java', 10)Copy the code

Result: We’re going to add some logging. The ordinary python function we’re going to add some logging. I’m Java and I’m 10 years old

The above writing method, is not OK, is not, no matter any function, any parameter, are OK, as for *args,**kwargs what meaning, we can go baidu ah. I won’t go into that here

With that said, I hope you have a basic understanding of Python decorators.

I’ll leave an Easter egg here, the final code above, do you have any questions? Look carefully, if you can see it, welcome to leave a message to me, how not to see it, see me next time decomposition.