当前位置:网站首页>Decorator basic learning 02

Decorator basic learning 02

2022-07-07 04:53:00 zxr1002

Yesterday's review

Closure function

​ 1. Definition : Functions defined inside functions , And use the name in the local namespace of the external function

​ 2. One of the methods of parameter transmission : Add something to the same level, and then wrap it with a function to indent

​ 3. From the direction of return value, we study the value of using local namespace from the global

​ 4. In practical application, local namespace sets local namespace , The original local space is closed immediately after the execution of the function code body , But in the case of closure function, it will be different , It closes only when the internal local namespace ends

Decorator

​ 1. The essence : Without changing the original calling method and internal code of the installed function, add new functions to the installed function

​ 2. principle : Closed to modification , For extension development

Decorator important derivation process

​ 1. Count the running time of a function

​ 2. The code that counts the running time of a function is encapsulated into a function

​ 3. Directly repacking into a function will change the calling method

​ 4. Try to pass parameters with closure function

​ 5. Replace the function of the original function with a duplicate name

​ 6. The parameters of the function

​ 7. Function return value

Decorator template

def outer( The function name of the decorated function ):
	def inner(*args, **kwargs):
        print(' Perform the operations that can be done before the decorated object ')
        res = func(*args, **kwargs)
        print(' Perform the operations that can be done after the decorated object ')
        return res
    return  Inner function name 

''' For two places *args and **kwargs The role of '''
def index(*args,**kwargs):
	pass

def func(*args,**kwargs):
	index(*args,**kwargs)
'''
args = ([1,2,3,4],)
kwargs = {'name':'jason','age':18}
index(*([1,2,3,4],),**{'name':'jason','age':18})
index([1,2,3,4],name='jason',age=18)
 Switching from one place to another is actually giving func What to wear is equivalent to giving index What to pass on 
'''
func([1,2,3,4],name='jason',age=18)
'''
[1,2,3,4], Is the redundant position parameter given args Take a data value , In the form of a tuple 
name='jason',age=18, Is the redundant keyword parameter given kwargs, In the form of a dictionary 
'''

Decorator grammar sugar

@outer  #  It's equivalent to this ,index = outer(index)
def index():
    pass

Decorator repair technology

from functools import  wraps
def outer(func_name):
    @wraps(func_name)  #  It is to make the decorator not easy to be found by others , To truly confuse the false with the true , Will not affect the code , You can write it or not 
    def inner(*args, **kwargs):
        print(' Perform additional operations that can be done before the decorated object ')
        res = func_name(*args, **kwargs)
        print(' Perform additional operations that can be done after the decorated object ')
        return res
    return inner

Today's content

Homework explanation

1. Write a user authentication decorator 
   The basic requirements 
    The identity must be verified before executing each function  eg: jason 123
   High practice ( It's a little difficult )
    Execute the decorated function   As long as the certification is successful once   Then the subsequent verification passes 
      function :register login transfer withdraw 
    Tips : Global variables   Record whether the current user is authenticated 
is_login = {'is_login': False, }  #  If the variable type is changed in the local namespace, there is no need to create a new name 
#  Write decorators 
def lonin_auth(func_name):
    def inner(*args, **kwargs):
        #  Judge the global dictionary is_login Whether the corresponding value True
        if is_login.get('is_login'):
            #  If it is True, It means that the user has logged in , Directly ask him to perform the operation to be performed 
            res = func_name(*args, **kwargs)
            return res
        #  Verify user identity 
        username = input(' enter one user name :').strip()
        password = input(' Input password :').strip()
        if username == 'jason' and password == '123':
            res = func_name(*args, **kwargs)
            #  After successful login , Perform what the user wants 
            is_login['is_login'] = True  #  Records after user login 
            return res
        else:
            print(' Insufficient user name permission ')
    return inner
@lonin_auth
def register():
    print(' Registration function ')
@lonin_auth
def login():
    print(' Login function ')
@lonin_auth
def transfer():
    print(' Transfer function ')
@lonin_auth
def withdraw():
    print(' Embody function ')

register()
login()
transfer()
withdraw()

Multi layer decorator

def outter1(func1):  # func1 be equal to wrapper2
    print(' To load the outter1')
    def wrapper1(*args, **kwargs):
        print(' Yes wrapper1')
        res1 = func1(*args, **kwargs)
        return res1
    return wrapper1

def outter2(func2):  # func2 be equal to wrapper3
    print(' To load the outter2')
    def wrapper2(*args, **kwargs):
        print(' Yes wrapper2')
        res2 = func2(*args, **kwargs)
        return res2
    return wrapper2

def outter3(func3):  # func3 Equal to real index function 
    print(' To load the outter3')
    def wrapper3(*args, **kwargs):
        print(' Yes wrapper3')
        res3 = func3(*args, **kwargs)
        return res3
    return wrapper3


@outter1  # index = outter1(wrapper2)
@outter2  # wrapper2 = outter2(wrapper3)
@outter3  # rapper3 = outter3( It's true index Function name )
def index():
    print('from index')
index()
'''
 The function of grammar sugar :
    1. It will automatically pass the following function as a parameter to @ Function name after symbol ( Bracketed call )
    2. If there is a syntax sugar above the syntax sugar, its return value is not the function name , It depends on the return value after he calls the function 
    3.wrapper3 = outter3( It's true index Function name ) Medium wrapper3 Is a function name , Then there is a grammar sugar on it , And then it triggers 1 Conditions 
    ....
    4. Last use index To receive 
 result 
 To load the outter3
 To load the outter2
 To load the outter1
 Yes wrapper1
 Yes wrapper2
 Yes wrapper3
from index
'''

There are ornaments for reference

1. Add parameters in

image-20220706205729452

2. stay inner Add parameters to

image-20220706211139127

3. The right way of thinking

image-20220706212246741
def outer(condition,type_user):
    def login_auth(func_name):  #  No other formal parameters can be filled here 
        def inner(*args, **kwargs):  #  You can no longer fill in the parameters required by non decorated objects 
            username = input('username>>>:').strip()
            password = input('password>>>:').strip()
            #  Different codes should be executed according to the needs of users 
            if type_user =='jason':print('VIP')
            if condition == ' list ':
                print(' Use lists as data sources ')
            elif condition == ' Dictionaries ':
                print(' Use dictionaries as data sources ')
            elif condition == ' file ':
                print(' Use files as data sources ')
            else:
                print(' At present, there are only the above ways ')
        return inner
    return login_auth
@outer(' file ','jason')  #  Parenthesized function name execution priority    @login_auth
def index():
    print('from index')
index()
'''
 Illustrate with examples 
 Multiple data sources can be switched inside the decorator 
    1. Originally, the decorator was executed step by step 
    2. Now, after obtaining the user name, there are many situations that are no longer directly executed downward , The implication is that the branch situation needs to be used somewhere 
    3.      if condition == ' list ':
                print(' Use lists as data sources ')
            elif condition == ' Dictionaries ':
                print(' Use dictionaries as data sources ')
            elif condition == ' file ':
                print(' Use files as data sources ')
            else:
                print(' At present, there are only the above ways ')
         This is the time condition Is an unfixed value , It can be a list 、 Dictionary or file , And this value is from us , Then there are two ways to transfer values in a function , At this time, it depends on which kind of value transfer 
    4. Add a layer of functions on the outside 
 summary : If we write another decorator , Its internal needs to pass in additional data to control the branch of the code , In this case, you can set another function on the original basis , And you can pass in multiple values , There is no need to nest functions 
'''

Recursive function

1. Introduction to recursive functions

#  Call directly : Call yourself 
def index():
    print('from index')
    index()
index()
#  Indirect invocation : The two functions call each other directly 
def index():
    print('from index')
    func()
def func():
    print('from func')
    index()
'''
 stay python There is a limit to how many times you can call yourself in , The official limit is 1000  Sometimes there may be a little deviation (997 998...)
'''
import sys
print(sys.getrecursionlimit())  # 1000   Get the maximum number of recursion 
sys.setrecursionlimit(2000)  #  The maximum number of times can be modified 
print(sys.getrecursionlimit())

2. Application scenarios of recursive functions

​ Recurrence : Look for the answer layer by layer

​ to flash back : Deduce the final answer according to the known conditions

​ Conditions : Each call is closer to the answer , It's simpler every time , Finally, there must be an end condition

​ Example description :

l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]]
#  Cycle through all the numbers in the list 
'''
 The analysis process :
1.for loop l1 All the data values in it 
2. Judge whether the current data value is a number   If so, print 
3. If not, continue for All data values in the loop 
4. Judge whether the current data value is a number   If so, print 
5. If not, continue for All data values in the loop 
6. Judge whether the current data value is a number   If so, print 
....
 thus it can be seen , There is always a piece of code that repeats 
'''
image-20220706215509275
def get_num(l1):
    for i in l1:
        if isinstance(i,int):
            print(i)
        else:
            get_num(i)
get_num(l1)

The dichotomy of algorithms

1. What is algorithm ?

​ Algorithm is the way to solve the problem , The algorithm is always improving , But there are few perfect algorithms .

2. Dichotomy

​ It is the simplest algorithm in the algorithm , It is mainly used in ordered sequences , The principle is to halve the original sequence every time you search , An algorithm that gradually reduces the search range

​ Take the median every time , If it is high, continue to take down the median value of the half , If it is low, take the median value of the upper half , And so on , Finally, find the correct guess .

​ The defects that exist : If the number searched is at the beginning or end Then dichotomy is less efficient , Only ordered sequences can be found .

Example show :

l1 = [2, 4, 6, 8, 10, 15, 18, 23, 34, 56, 78, 90, 101, 120]
def get_num(l1, target_num):
    #  Add the end condition of recursive function 
    if len(l1) == 0:
        print(' Can't find ')
        return
    # 1. Get the middle number , Divide the total length 2, It's the value in the middle 
    middle_index = len(l1) // 2
    middle_value = l1[middle_index]
    # 2. Judge whether the intermediate value obtained is smaller than the target number we are looking for , And then discuss the situation , utilize if..elif
    if target_num > middle_value:
        # 3. If the objective function is greater than the median , Explain that the objective function is on the right , Since it is a freshman, it means that if it is larger than itself, it can be narrowed down a little 
        right_l1 = l1[middle_index + 1:]
        # 3.  The same operation is carried out on the right , Find the intermediate value and compare 
        #  After analysis, we know that   Recursive functions should be used 
        print(right_l1)
        get_num(right_l1, target_num)
    elif target_num < middle_value:
        # 4. It indicates that the number to be searched is on the left half of the dataset    How to intercept the left half 
        left_l1 = l1[:middle_index]  #  The left side doesn't need -1, The index is regardless of the end  
        # 4. The same operation is carried out on the left , Find the intermediate value and compare 
        #  After analysis, we know that   Recursive functions should be used 
        print(left_l1)
        get_num(left_l1, target_num)
    else:
        print(target_num)
get_num(l1, 18)
原网站

版权声明
本文为[zxr1002]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207062231024911.html