Closure function and decorator

Keywords: iOS

Closure function

Definition of closure function:

Closed: a function defined within a function

Package: the inner function references the name of the outer function scope

There are two ways to pass values to function bodies:

1. transmitting ginseng

 

def index1(username):
    print(username)

 

2. closure

def outter(x,y):  #Passing parameters in a function, in res1 Call in, equivalent to x=1,y=40
    # x = 1
    # y = 40
    def my_max():
        if x > y:
            return x
        return y
    return my_max
res1 = outter(1,40)  # res Namely my_max Memory address of the function
print(res1())   #If you want to stop printing 1 and 40, you can only end the program or transfer other parameters.
print(res1())
print(res1())
res2 = outter(90,200)
print(res2())
print(res2())
import requests  

def outter(url):  #Pass parameters to functions in my_jd Parameter defined in to parameter
    # url = 'https://www.jd.com 'ා fixed reference
    def my_get():
        response = requests.get(url)
        if response.status_code == 200:  
            print(len(response.text))
    return my_get
my_jd = outter('https://www.jd.com')  #my_jd Received is my_get Memory address of
my_jd()
my_jd()
my_baidu = outter('https://www.baidu.com')
my_baidu()
my_baidu()
my_baidu()
my_baidu()
my_baidu()

 

 

Decorator

Decorator:

Tool: it's a tool

Decoration: add new functions to the decorated objects

Why use decorators?

Open and closed principle:

Open: open to expansion

Closed: open to modification

There are two principles that decorators (callable objects) must follow:

1. Do not change the source code of the decorated object

2. Do not change the call mode of the decorated object (callable object)

 

First write an example of the time module

import time
def index():
    time.sleep(3)   # Give Way CPU Sleep for 3 seconds.
    print('Open up')

start = time.time()  # Time at the beginning of program run
index()
end = time.time()    #Time at the end of the program
print('index run time:%s'%(end-start))  # Calculate the time taken by the program from start to end

 

How to write a time calculating decorator? Different function names can be applied

import time
def index():
    time.sleep(3)
    print('Open up')

def outter(func):  # func = ancestral index Memory address of the function
    def get_time():
        start = time.time()
        func()  # func = index Memory address of the function() Direct call
        end = time.time()
        print('index run time:%s'%(end-start))
    return get_time
index = outter(index)  # outter(ancestral index Function memory address)
# index point get_time Memory address of the function
index()

How to write a decorator with and without parameters

import time
def index():   #Parameter free function
    time.sleep(3)
    print('Open up')
    return 'index'
res1 = index()

def login(name): #Parametric function
    time.sleep(1)
    print('%s is s'%name)
    return 'login'
res = login('zhangsan')

def outter(func):  # func = ancestral login Memory address of the function
    def get_time(*args, **kwargs):  # write*args and**kwargs It can support both with and without parameters, and can receive any number of parameters.
        start = time.time()
        res = func(*args, **kwargs)  # ancestral login Memory address of the function() Direct call  func('egon')
        end = time.time()
        print('func run time:%s'%(end-start))
        return res
    return get_time
login = outter(login)

Grammatical sugar

def outter(func):  # func = ancestral index Memory address of the function
    def get_time(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)  # ancestral index Memory address of the function() Direct call  
        end = time.time()
        print('func run time:%s'%(end-start))
        return res
    return get_time


@outter   # Grammar sugar, equivalent to index = outter(index),outter It will directly pass in the function name closest to him as its own parameter.
def index():
    time.sleep(3)
    print('Open up')
    return 'index'

 

Decorator template

def outter(func):
    def inner(*args, **kwargs)
        print('What can be done before the decorated function is executed')
        res = func(*args, **kwargs)
        print('What can be done after the decorated function is executed')
        return res
    return inner

Certified decorator

Before executing the function index, you must enter the correct user name and password before executing the index. Otherwise, you will be prompted to enter an error to end the program.

import time
user_dic = {'is_login':None}  #Define a dictionary to store user login status

def login_auth(func):
    # func = index
    def inner(*args,**kwargs):
        if user_dic['is_login']:  # If the user is already logged in
            res = func(*args, **kwargs)  
            return res  #Return parameters directly
        else:
            username = input('please input your username>>>:').strip()
            password = input('please input your password>>>:').strip()
            if username == 'wu' and password == '123':
                user_dic['is_login'] = True
                res = func(*args,**kwargs)
                return res
            else:
                print('username or password error')
    return inner

Decorator supplement @ wraps

def outter(func):
    @wraps(func)    
    def inner(*args, **kwargs)
        print('What can be done before the decorated function is executed')
        res = func(*args, **kwargs)
        print('What can be done after the decorated function is executed')
        return res
    return inner

# When users view the function name of the decorated function, they will see the decorated function itself.
# When users view the comments of the decorated function, they will see the comments of the decorated function.

Posted by matafy on Tue, 29 Oct 2019 10:28:10 -0700