current position:Home>Why do Python decorators need double-layer nesting and business scenarios

Why do Python decorators need double-layer nesting and business scenarios

2022-02-02 15:05:02 adorable_

An ordinary ornament is written :

def log(func):
    def wrapper(*args, **kwargs):
        print(' Called function '.format(func.__name__))
        return func(*args, **kwargs)
    return wrapper

Here's a question , Why is it nested inside wrapper function ?

reason :

  1. If there is no nesting , In fact, the decorator returns either the definition of the original function , Or it's not a function at all , That is, the function is not decorated at all .
  2. Even if you happen to get the desired result, the decorator runs in the definition stage , This should not have happened , Because that means not calling functions , There will still be output , And the effect cannot be reproduced when the function is called .

The code description is as follows :
1、 If you directly a single-layer decorator

def log(func):                                          #1
    print(' Called function {}'.format(func.__name__))        #2
    return func()                                       #3

@log                                                    #4
def now():                                              #5
    print('hello world !')

now()

   here #4 When it runs, it will run #2 Of print, And the decorator requires #3 return A function , Not the value of the function ( The correct way of writing is return func), therefore #3 A grammatical error of , Will report a mistake TypeError: 'NoneType' object is not callable
 Insert picture description here
2、 If corrected to return func

def log(func):                                          #1
    print(' Called function {}'.format(func.__name__))        #2
    return func                                         #3

@log                                                    #4
def now():                                              #5
    print('hello world !')

now()

   This will not report mistakes , But it will be there. @log Directly execute the contents of the decorator , The perform print, At this time, the decorator returns the original function , So we call the function later. now You can't trigger the decorator . That is, there is no call now In this case, we will also get an output statement of the decorator , Because at this time log The function executes , So you need two levels of nesting to return a function
 Insert picture description here

python Why did the designer design so

Why not equate the execution order of the single-layer decorator with the current execution order of the double-layer decorator ?

  • First, the two-tier structure can transfer the decorated function now Parameters of
  • The second is not to change the function now And the function log The original structure , because log It's a function in itself , It has the same execution order as other functions
def log(func):
    def wrapper(*args, **kwargs):
        print(' Called function '.format(func.__name__))
        return func(*args, **kwargs)
    return wrapper

@log
def now(x):
    print('hello {} !'.format(x))

now('world')

It's exactly equivalent to now=log(now)

explain :

  • Decorator is equivalent to modifying the original function definition , The function definition is still returned ! Instead of simply returning the result of the function
  • At this point, call the decorated function, and actually execute the decorated function ( That is, it can be understood as calling a function with a decorator , The actual definition of this function is not what you see , It was modified by the decorator )
  • Once defined, you can reuse , It's like defining a function
  • Personally, I think if you use a decorator , The way of writing without nesting is completely contrary to the original intention of the decorator , You don't have to use a decorator at this time , It's better to call the real function directly

What is a decorator , What's the function , What business scenarios can it be used in ?

Concept :

  1. The implementation of decorators is supported by closures
  2. Decorators are essentially ⼀ individual python function , It can add additional functionality to other functions without any code changes
  3. The return value of the decorator is a decorated Function definition , It's also ⼀ Object of a function , It is often used in scenarios with faceted requirements , Implement routing parameters ,flask The routing parameters of depend on the decorator , Browser pass url Route to decorator , To access the view function to get the returned HTML page
  4. The decorator took place in Definition Stage instead of perform Stage

Application scenarios :

  1. You can add a time calculation function to the outer function , Calculate function run time ;
  2. Calculate the number of function runs ;
  3. It can be used in the routing parameters of the framework ;
  4. Inserting log , Run log as a function ;
  5. Transaction processing , You can let functions achieve transaction consistency , Let the functions either run together successfully , Or run together and fail ;
  6. cache , Implement cache processing ;
  7. Verification of authority , Put the code of permission verification on the outer layer of the function , Implement permission verification ;

copyright notice
author[adorable_],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/02/202202021504494234.html

Random recommended