Decorator Advanced

One: decorator

On the basis of not changing the original function, additional functions are added.

The return value of the decorator is a function object.

Decorator application: logging, performance testing, transaction processing, caching and other scenarios.

 

 

Two: the formation process of the decorator

Application of a function: calculating execution time

import time
def func1():
    print('in func1')
def timer(func):
    def inner():
            start_time=time.time()
            func()
            end_time=time.time()
            print(end_time-start_time)
    return inner
func1 = timer (func1)
func1()

 

It is too troublesome to use func1=timer(func1) when applying multiple functions, so there is syntactic sugar.

 

No parameter decorator (simple decorator)

import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

@timer # ==> func1 = timer (func1)
def func1():
    print('in func1')
func1()

Universal decorator (function with parameters)

def  wrapper(func):
    def inner(*args,**kwargs):
        ret = func (* args , ** kwargs )
         return ret
     return inner
# @wrapper
# def func():
#     print()
# func()

Interpretation: The omitted part is used when we want to call this decorator to execute the function.

 

Decorator with parameters (see function name and declaration information)

def  wrapper(func):
    def inner(*args,**kwargs):
        ret = func (* args , ** kwargs )
         return ret
     return inner
@wrapper
def func():
    print()
func()
from functools import wraps

def deco(func):
    @wraps(func) #Add just above the innermost function
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def index():
    '''Ha ha ha ha'''
    print('from index')

print(index.__doc__)

 

 

with flag decorator

def outer(flag):
    print('Don't go to work')
    def wrapper(func):
        print('It's been a week')
        def inner(*args,**kwargs):
            if flag:
                print('Decorators are a headache')
            ret=func(*args,**kwargs)
            if flag:
                print('I'm going, it's not over yet')
            return ret
        return inner
    return wrapper
@outer(True)
def func():
    print('Finally on vacation')
func()

bug: @outer ( True ) must put 500

Improve

flag = True
def wrapper_out(flag):
    def wrapper(func):
        def inner(*args,**kwargs):
            '''Before executing the function'''
            if flag:
                ret = func (* args , ** kwargs )
                '''After executing the function'''
                print(222)
                return ret
             else :
                ret = func ()
                return ret
        return inner
    return wrapper

@wrapper_out(flag) #The first step is to call wrapper_out(flag) and receive the return value wrapper
def func(): #The second step is @wrapper, that is, func = wrapper(func)
    print(111)
func()

 

 

 

Multiple decorators decorate a function

def wrapper1(func):
    def inner():
        print('wrapper1 ,before func')
        func()
        print('wrapper1 ,after func')
    return inner

def wrapper2(func):
    def inner():
        print('wrapper2 ,before func')
        func()
        print('wrapper2 ,after func')
    return inner

@wrapper2
@wrapper1
def f():
    print('in f')

f()

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325768714&siteId=291194637