python-decorator

---Restore content begins---

Decorator: The essence of a decorator is a function, and its main purpose is to decorate other functions (add new functions to other functions)!

Some features of decorators:

  • The source code of the decorated function cannot be modified
  • The way the decorated function is called cannot be changed

Understand the following three points:

  • A function is a variable (the function name can be analogous to the variable name, and the function body can be analogous to the content of the variable!)
  • Higher order functions:
    •   Pass the function name of one function as an argument to another function
    •        The return value of the function contains the function name
#A higher-order function that satisfies one of the two conditions is called a higher-order function 
# def bar(): #Pass the function name as an argument 
#      print("int the bar...")
#
# def outer(func):
#     print("in the outer...")
#     func()
#
# outer(bar) #The 
name of the passed function is an actual parameter, and the source code of the decorated function is not modified
#return function name def bar(): print ( " int the bar... " ) def outer(func): print("in the outer...") return func bar = outer(bar) bar() #Return the function name without modifying the calling method of the original function

 

    •   Nested functions: Using a def statement in a function body to define another function is called a nested function. Note that it is not a call !

Decorator == higher-order function + nested function:

  1. Use higher-order functions (the feature of passing function names as parameters) to pass the function to be decorated to the decorator function to add new functionality without changing the source code of the decorated function!
  2. Utilizing higher-order functions (returning the function name) without modifying how the decorated function is called.
  3. Use nested functions to encapsulate the decorator into a function and call it with the help of syntactic sugar @.
'''
Use the decorator to print out the execution time of the function
'''
import time

def timmer(func):
    def wrapper():
        start_time = time.time()
        func()
        stop_time = time.time()
        print("The func.__name__ running %s second" % (stop_time-start_time))
    return wrapper

@timmer #Syntax      sugar for decorators, this sentence is equivalent to test1 = timmer(test1) 
def test1():
    time.sleep(1)
@timmer
def test2(): #Syntax sugar for decorators, this sentence is equivalent to test2 = timmer(test2), 
    time.sleep(2 )

test1() #The   source code and calling method of the original function have not changed 
test2()


The above original function and decorator have no parameters, and the decorator with parameters:

'''
Use the decorator to print out the execution time of the function
'''
import time

def timmer(func):
     def wrapper(*args,**kwargs):    #The parameters of the decorated function are passed to the wrapper, so the wrapper function needs to be able to receive parameters 
        start_time = time.time()
        func(*args,**kwargs)
        stop_time = time.time()
        print("The %s running %s second" % (func.__name__,stop_time-start_time))
    return wrapper

@timmer #Syntax      sugar for decorators, this sentence is equivalent to test = timmer(test1) 
def test1(name):
     print (name.center(50, " - " ))
    time.sleep(1)
@timmer
def test2(name): #Syntax sugar for decorators, this sentence is equivalent to test = timmer(test2), 
    print (name.center(50, " - " ))
    time.sleep(2)

test1( " LFY " )   # The source code and calling method of the original function have not changed 
test2 ( " WXZ " )


There is a requirement to add different functions to different decorated functions according to the incoming parameters!

Two methods:

  • Write another decorator (not recommended).
  • The second method selects different decorators according to the parameters.

For the decorators on the test1 function and the test2 function, the function of displaying the execution time is added; now there are the following requirements: for the test1 unchanged, the function of the function execution time is still added, and for the test2 function, the start execution time and the end of the function are added to print out the function time.

# *-*coding:utf-8 *-*
# Auth: wangxz
import  time

def timmer(type):    # is to nest a function in the outer layer of the decorator 
    def out_wrapper(func):
         def wrapper(*args, ** kwargs):
             if type == " one " :
                start_time = time.time()
                func(*args, **kwargs)
                stop_time = time.time()
                print("The %s running %s second" % (func.__name__, stop_time - start_time))
            elif type == "two":
                print("The %s runging start at %s" % (func.__name__, time.time()))
                func(*args, **kwargs)
                print("The %s runging staop at %s" % (func.__name__, time.time()))
        return wrapper
    return out_wrapper

@timmer( " one " )   # # Note that this actual parameter is passed to the formal parameter 
def test1(name):
     print (name.center(50, " - " ))
    time.sleep(1)

@timmer( " two " ) #
 def test2(name): #Syntax sugar for decorators, this sentence is equivalent to test = timmer(test2), 
    print (name.center(50, " - " ))
    time.sleep(2)

test1( " WXZ " )    #Select different decorators according to the parameters of the passed syntactic sugar 
test2( " LFY " )      #

The execution result of this function code is as follows:

#The result of code execution is as follows: 
-----------------------WXZ------------------- ----- 
The test1 running 1.0000572204589844 second
The test2 runging start at 1524373351.098816
-----------------------LFY------------------------
The test2 runging staop at 1524373353.0989301

Process finished with exit code 0

have to be aware of is:

    If the decorated function has a return value, then in the wrapper() function of the decorator, you also need to use the return statement to return the result of the function.

 

 

 

 

---End of recovery content---

Guess you like

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