Supplement and iterator of decorator

I. login authentication function

user_info = {
    'user': None
}
#Login function authentication
def login():
    username = input('Please enter the account name:').strip()
    password = input('Please input a password:').strip()
    with open(r'a.txt', 'r', encoding='utf-8')as f:
        for line in f:
            f.readline()
            name, pwd = line.strip('\n').split(':')#Cross assignment returns ['yafeng','666 ']
    if username == name and password == pwd:
        print('Login successfully!')
        user_info['user'] = username
    else:
        print('Login failed!')

def login_auth(func):

    def inner(*args, **kwargs):
        #Already logged in, will be directly called by the decoration object and returned
        if user_info.get('user'):#If it's on the list
            res = func(*args, **kwargs)

            return res
        else:
            print('Please login first.')
            login()
            '''
            //Note: no matter what judgment appears in the inner,
            //Finally, return "decorated object after call" func(*args, **kwargs)
             '''
            res = func(*args, **kwargs)#Note that you must return res at this time, otherwise from 1 will not print out
            return res

    return inner


@login_auth
def func1():
    print('from 1')
    pass

@login_auth
def func2():
    print('from 2')
    pass
@login_auth
def func3():
    print('from 3')
    pass

while True:
    func1()
    input('Please enter the operation')
    func2()
    func3()

II. Superimposed decorators of decorators

Sometimes we want to decorate a decorated function with multiple functions. Although we can also add multiple functions to a decorator, it will appear that the code is very long and the readability is not high. Moreover, if we want to modify the function of the decorator function in the future, we have to delete it. The best way is to fix which one of the decorators Function, we want to decorate the function more than this, then the overlay decorator will come into use.

  • Overlay decorator
In the same decorated object, add multiple decorators and execute.
@ decoration 1
 @ decoration 2
 @ decoration 3
 def decorated object ():
    pass

Note: order of overlay decorators
    Decoration order: from bottom to top
    Order of execution: from top to bottom
  • Stacker demonstration
def wrapper1(func):
    def inner1(*args, **kwargs):
        print('1---start')
        # When the decorated object is called, if there are other decorators, the inner in other decorators will be executed first
        # inner2
        res = func(*args, **kwargs)
        print('1---end')
        return res

    return inner1


def wrapper2(func):
    def inner2(*args, **kwargs):
        print('2---start')
        res = func(*args, **kwargs)
        print('2---end')
        return res

    return inner2


def wrapper3(func):
    def inner3(*args, **kwargs):
        print('3---start')
        res = func(*args, **kwargs)
        print('3---end')
        return res

    return inner3


'''
//The decoration sequence and execution sequence of superimposed decorators:
    - Decoration order: call wrapper Decorator gets the return value inner
        //Decoration from bottom to top

    - Execution sequence: Return value after calling decoration inner
        //From top to bottom
'''


@wrapper1  # index<---inner1 = wrapper1(inner2)
@wrapper2  # inner2 = wrapper2(inner3)
@wrapper3  # inner3 = wrapper3(index)
def index():  # Decorated object   # inner1 --->
    print('from index...')


# Decorating
inner3 = wrapper3(index)
inner2 = wrapper2(inner3)
inner1 = wrapper1(inner2)

'''
inner1()
inner2()
inner3()
index()
'''
index()  # Execute here # inner1() --> inner2() ---> inner3()
>>>1---start
2---start
3---start
from index...
3---end
2---end
1---end
  • Paramedic decorator

Before, we used parameterless decorators, that is, when decorating the decorated objects, there was no parameter passing

'''
# Here is the parameterless decorator
@wrapper1  # inner1 = wrapper1(inner2)
@wrapper2  # inner2 = wrapper2(inner3)
@wrapper3
'''

# Parameter decorator: in some cases, we need to classify the permissions of users
'''
# Here is the reference decorator
@wrapper1(Parameter 1)  # inner1 = wrapper1(inner2)
@wrapper2(Parameter 2)  # inner2 = wrapper2(inner3)
@wrapper3(Parameter 3)
'''
  • Paramedic decorator
def user_auth(user_role):  # 'SVIP'
    def wrapper(func):
        def inner(*args, **kwargs):
            if user_role == 'SVIP':
                # Add super user features
                res = func(*args, **kwargs)
                return res
            elif user_role == 'Ordinary users':
                print('Ordinary users')
                # Add functions for ordinary users
                res = func(*args, **kwargs)
                return res

        return inner
    return wrapper


# Decorated object
# @user_auth('SVIP')
wrapper = user_auth('Ordinary users')
@wrapper
# @user_auth('SVIP')  # wrapper = user_auth('normal user ')
@wrapper  #< --- return resu lt (wrapper) < --- user_auth()
def index():
    pass
index()
  • wraps
'''
wraps: (Understanding)
    //Is a repair tool, which repairs the space of the decorated object.
    from functools import wraps

'''
from functools import wraps


def wrapper(func):

    @wraps(func)  # Modify namespace: inner -- func
    def inner(*args, **kwargs):
        '''
        //Here is the note for the decorator
        :param func:
        :return:
        '''
        res = func(*args, **kwargs)
        return res
    return inner  # ---> func


@wrapper
def index():
    '''
    //Here is the comment for the index function
    :return:
    '''
    pass


print(index)  # Function object

# Function object. doc: view comments inside a function
print(index.__doc__)  # inner.__doc__

III. iterator

  • What is iterator

Iteration: iteration is a repeated process, and each repetition is based on the result of the previous one

x = 10
while True:
    print(x)
#This is a repetitive process, but it is not based on the last result

l = [1,2,3,4]
n = 0
while n < len(l):
    print(l[n])
    n  += 1
>>>1
2
3
4
#This is an iteration. Each result is based on the previous one

To understand iterations, we need to understand what iterations are

stay python All built-in._iter_()Method objects are called iteratable objects, so the following are all iteratable objects:
str
list
dict
tuple
set
file

After we understand the concept of iteratable objects, we can define iterators, which are tools for updating values.

After we know what an iterator is and what an iteratable object is, we can say what an iterator object is

Iterator object:

The return value from the iteratable object execution. The iterator method is the iterator object. next, we can get the value of each element with the iterator object

s = {1, 2, 3}
iter_s = s.__iter__()#Iter_sis the iterator object
print(iter_s.__next__())
print(iter_s.__next__())
print(iter_s.__next__())
print(iter_s.__next__())
>>>Traceback (most recent call last):
  File "D:/python Of pycharm/Formal course/day12/iterator.py", line 53, in <module>
    print(iter_s.__next__())
StopIteration
1
2
3

Although we get the elements in each set, we will report an error, that is, there is an error of StopIteration. This error means that when the value I print exceeds all the capacities in one container, an error will be reported, because there is no object for us to access, so can we get all the elements in it and not report an error? The answer is yes . You need to use try

s = {1, 2, 3}
iter_s = s.__iter__()#Iter_sis the iterator object
while True:
    try:
        print(iter_s.__next__())

    except StopIteration:
        break
>>>1
2
3
  • Summary ratio comparison

    Objects that can be iterated:

    Features: built in with the - iter - method, all of them are iterative objects. Executing the method will get an iterator object

    Characteristics of iterator objects:

    Built in - next - method, each execution will get a value in the iterator object

    Built in - iter - method, execution will get iterator itself

    Features of iterators:

    Advantage: provides a method independent of index value

    Iterators save more space and memory

    Disadvantage: the value is troublesome, only one value can be taken

    Can't use len to get a specific value

Keywords: Python encoding Pycharm

Added by pratheshshah on Wed, 13 Nov 2019 13:40:47 +0200