day17 decorators have parameters, iterators and generators

1. There reference decorator

1.1 knowledge base

@ Due to limitations of syntactic sugar, the outter only one function parameter, and is used only to receive the memory address of the object decorated

def outter(func):
    # func = 函数的内存地址
    def wrapper(*args,**kwargs):
        #装饰器内容
        res=func(*args,**kwargs)
        return res
    return wrapper

# @outter # index=outter(index) # index=>wrapper
@outter # outter(index)
def index(x,y):
    print(x,y)

1.2 parameter for realizing the decorator

For decorators auth, and now we need to get the value of the parameter db_type to confirm the source of user information

Example 1: no syntactic sugar, using transfer function parameters

def auth(func,db_type):
    def wrapper(*args, **kwargs):
        name=input('your name>>>: ').strip()
        pwd=input('your password>>>: ').strip()
        if db_type == 'file':
            print('基于文件的验证')
            if name == 'egon' and pwd == '123':
                res = func(*args, **kwargs)
                return res
            else:
                print('user or password error')
        elif db_type == 'mysql':
            print('基于mysql的验证')
        elif db_type == 'ldap':
            print('基于ldap的验证')
        else:
            print('不支持该db_type')
    return wrapper
def index(x,y):
    print('index->>%s:%s' %(x,y))
def home(name):
    print('home->>%s' %name)
def transfer():
    print('transfer')


index=auth(index,'file')
home=auth(home,'mysql')
transfer=auth(transfer,'ldap')
index(1,2)
home('egon')
transfer()

Example 2: syntactic sugar, parameter passing mode using the closure

def auth(db_type):
    def deco(func):
        def wrapper(*args, **kwargs):
            name = input('your name>>>: ').strip()
            pwd = input('your password>>>: ').strip()

            if db_type == 'file':
                print('基于文件的验证')
                if name == 'egon' and pwd == '123':
                    res = func(*args, **kwargs)  
                    return res
                else:
                    print('user or password error')
            elif db_type == 'mysql':
                print('基于mysql的验证')
            elif db_type == 'ldap':
                print('基于ldap的验证')
            else:
                print('不支持该db_type')
        return wrapper
    return deco

# @deco # index=deco(index) # index=wrapper
@auth(db_type='file')  
def index(x, y):
    print('index->>%s:%s' % (x, y))
 # @deco # home=deco(home) # home=wrapper
@auth(db_type='mysql') 
def home(name):
    print('home->>%s' % name)

@auth(db_type='ldap')  # 账号密码的来源是ldap
def transfer():
    print('transfer')

1.3 There decorator template parameters

def 有参装饰器(x,y,z):#可以传任意个值
    def outter(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res
        return wrapper
    return outter

@有参装饰器(1,y=2,z=3)
def 被装饰对象():
    pass

1.4 additional knowledge decorator

Perpetrating a fraud

The original memory address of the function names that refer to the back door into a wrapper function, so it should be done with the original wrapper function the same job

wrapper comes with built-in properties and attributes of the original function is not the same

from functools import wraps

def outter(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs) # res=index(1,2)
        return res
    # 手动将原函数的属性赋值给wrapper函数
    # 1、函数wrapper.__name__ = 原函数.__name__
    # 2、函数wrapper.__doc__ = 原函数.__doc__
    # wrapper.__name__ = func.__name__
    # wrapper.__doc__ = func.__doc__

    return wrapper

@outter # index=outter(index)
def index(x,y):
    """这个是主页功能"""
    print(x,y)

print(index.__name__)
print(index.__doc__) #help(index)

2. iterator

2.1 What is an iterator

Iterator refers to the value of the iteration tools, iteration is an iterative process, each iteration is based on a result of continued, not simply repeat iteration

2.2 Why have iterators

Iterator iterative value is used tool, and a plurality of values ​​related to the type of the cycles are taken out:

Lists, strings, tuples, dictionaries, collections, open the file

l=['egon','liu','alex']
i=0
while i < len(l):
    print(l[i])
    i+=1

Iterative manner described above apply only to the value of the indexed data types: list, string, a tuple
order to address the limitations based on the index value of the iterator
python must be provided without depending on the way the index value, this is the iterator

2.3 How iterator

2.3.1 iterables:

Whenever built __iter__ method may be iterations are called objects

s1=''
# s1.__iter__()
l=[]
# l.__iter__()
t=(1,)
# t.__iter__()
d={'a':1}
# d.__iter__()
set1={1,2,3}
# set1.__iter__()
with open('a.txt',mode='w') as f:
    # f.__iter__()
    pass

2.3.2 iterator object:

__iter__ call method in iterable will convert iterator object

d={'a':1,'b':2,'c':3}
d_iterator=d.__iter__()
#方案1:迭代器的取值
print(d_iterator.__next__())
print(d_iterator.__next__())
print(d_iterator.__next__())
print(d_iterator.__next__()) # 抛出异常StopIteration
print('====>>>>>>') 
#方案2:在一个迭代器取值取干净的情况下,再对其取值值取不到
d_iterator=d.__iter__()
while True:
    try:
        print(d_iterator.__next__())
    except StopIteration:
        break

l=[1,2,3,4,5]
l_iterator=l.__iter__()
while True:
    try:
        print(l_iterator.__next__())
    except StopIteration:
        break

2.4 iterables the iterator object Detailed

2.4.1 iterables ( "can be converted into an iterator object"):

  • Method objects built __iter__ iterables ._ ITER _ (): iterator object obtained

2.4.2 iterator object:

  • __Next__ built object has built-in method and a method __iter__
    • Iterator object ._ Next _ (): get the next value of the iterator
    • Iterator object ._ iter _ (): get the iterator itself is useless
dic={'a':1,'b':2,'c':3}

dic_iterator=dic.__iter__()
print(dic_iterator is dic_iterator.__iter__().__iter__().__iter__())

2.4.3 expansion of knowledge: for loop works

The for loop can be called an iterator called loop

dic={'a':1,'b':2,'c':3}
for k in d:
    print(k)
with open('a.txt',mode='rt',encoding='utf-8') as f:
    for line in f: # f.__iter__()
        print(line)
list('hello') #原理同for循环     
  • . 1, d._ ITER _ () to get a iterator object
  • 2, iterator object ._ Next _ () get a return value, the return value is then assigned to k
  • 3, the cycle step 2 until raise StopIteration for loop will catch the exception and ends the cycle

2.4.4 What iteration object

Iterables: strings, lists, tuples, dictionaries, collections, file objects

Iterator objects: file object

s1=''
s1.__iter__()

l=[]
l.__iter__()

t=(1,)
t.__iter__()

d={'a':1}
d.__iter__()

set1={1,2,3}
set1.__iter__()

with open('a.txt',mode='w') as f:
    f.__iter__()
    f.__next__()

2.5 iterator summary

2.5.1 advantage

  • Provides a unified way the value of iterative sequence and non-sequence types.
  • Lazy evaluation: iterator object is represented by a data stream, you can call only when required to calculate a value next to it is the iterator itself, only one value at a time in memory, which can store infinite data streams for other types of containers, such as lists, all the elements need to be stored in memory, restricted memory size, the number of values ​​can be stored is limited.

2.5.2 shortcomings

  • Unless depletion, or can not get the iterator length
  • Remove only one value, not back to the beginning, more like a 'one-off', the only goal is to repeat the iterator produce the next method until the value of depletion, otherwise it will stay in one place, waiting for the next call next; if you want iterations of the same object again, you can only recall iter method to create a new iterator object, if there are two or more cycles using the same iterator, inevitably there will only be able to take to a recycling value.

3. Generator

Builder is a custom iterator, how to get a custom iterator

3.1 Custom iterator

Once the yield keyword in the presence of a function, the function does not perform the calling function member returns a code generating object, i.e., the iterator custom generator

def func():
    print('第一次')
    yield 1
    print('第二次')
    yield 2
    print('第三次')
    yield 3
    print('第四次')
g=func()
# 会触发函数体代码的运行,然后遇到yield停下来,将yield后的值
# 当做本次调用的结果返回
res1=g.__next__()
print(res1)#第一次  1
res2=g.__next__()
print(res2)
res3=g.__next__()
print(res3)
res4=g.__next__()#StopIteration

3.2 Applications

#自定义range函数
def my_range(start,stop,step=1):
    print('start...')
    while start < stop:
        yield start
        start+=step
    print('end....')
g=my_range(1,5,2) # 1 3
print(next(g))
print(next(g))
print(next(g))

for n in my_range(1,7,2):
    print(n)

3.3 summary

With the yield keyword, we have a way to achieve self-defined iterator. yield may be used to return values, but unlike the return, the function return is encountered once ended, and the yield can keep a running state function suspend function to return multiple values

Guess you like

Origin www.cnblogs.com/Henry121/p/12560785.html