Closures, iterators, generator

A closure

  1. In the nested function, using external non-internal functions global variables
  2. Role: data security protection
  3. Nature decorator is Closures
def func():
    avg_lst = []  # 自由变量
    def foo(pirce):
        avg_lst.append(pirce)
        avg = sum(avg_lst) / len(avg_lst)
        return avg
    return foo
ret = func()
print(ret(150000))
print(ret.__closure__) # 查询是不是闭包
print(ret.__code__.co_freevars) # 获取的是自由变量
print(ret.__code__.co_varnames) # 获取的是局部变量

Two iterators

2.1 iterables

View dir ()

内部含有__iter__方法的对象,都是可迭代对象。

Advantages: flexible, you can directly see the value

Disadvantages: total memory, not the value of the iteration

2.2 iterator

只要具有__iter__()方法__next__()方法就是迭代器

Advantages: save memory, memory mechanism

Disadvantages: not flexible, the operation is more complicated, you can not see the elements directly

Features: one-time (run gone), irreversibility (not retracted), an inert mechanism

2.3 iterables converted iterator

lst = [1,2,3,4,6]
new_list = lst.__iter__()  #将可迭代对象转换成迭代器

Essence 2.4 for loop

lst = [1,2,3,4,5,6,7,8,9]
new_lst = lst.__iter__()    #先转换成迭代器
while 1:
    try:
        print(new_lst.__next__())
    except StopIteration:
        break

Three generators

Builder essentially different iterators and iterator is an iterator python is built, they used the code generator is built

3.1 generator are built

  1. By writing your own generator function
  2. By derivation generator
  3. Built-in functions or module python

3.2 generator function

1. yield

The function of the return into the yield, so that it is not func function, but rather a function generator

def func():
    print(11)
    yield 22
ret = func()   #产生一个生成器
print(ret)

Output Results: <generator object func at 0x000000000223FE08>

When executed When the execution to yield keyword when we call the function of the function body code will be found that we want to declare a builder. Builder program will give us a return

Generators and iterators the same value

def func():
    print("111")
    yield 222
    print("333")
    yield 444
gener = func()
ret = gener.__next__()
print(ret)
ret2 = gener.__next__()
print(ret2)
ret3 = gener.__next__()
# 最后一个yield执行完毕,再次__next__()程序报错
print(ret3)

A generator function can be written more yield, when the program is running the last of yield, it continues to run behind the next () program will be given, corresponding to a yield a next, next exceed the number of yield, it will error, like iterators.

print(func().__next__()) # 坑 -- 会产生新的生成器
print(func().__next__())

yield and return the difference:

In general the return function is provided only one, his role is to terminate the function, and to the return value of the function's execution.

yield the generator function may be provided in a plurality, and that he does not terminate function, next will yield the corresponding acquisition element generates. yield will record the execution location, yield and be able to for a while loop inside the function temporarily suspended

2. seed

def gen(name):
    print(f'{name} ready to eat')
    while 1:
        food = yield
        print(f'{name} start to eat {food}')
dog = gen('alex')
next(dog)
dog.send('骨头') # 还可以给上一个yield发送值
dog.send('狗粮')
dog.send('香肠')

send and next () the difference:

Same point:

send and next () so that the generator can yield a corresponding downward once.

Yield value can be obtained is generated.

difference:

The first acquisition yield values ​​can only be used next can not send (can send (None)).

can send to yield a set value is transmitted.

3. yield from (python3) is the element-by-return iterables

def func():
    lst1 = ['卫龙', '老冰棍', '北冰洋', '牛羊配']
    lst2 = ['馒头', '花卷', '豆包', '大饼']
    yield from lst1
    yield from lst2
g = func()
for i in g:
    print(i)

After the list of all the elements of the first to return, then return to the second list

Guess you like

Origin www.cnblogs.com/lav3nder/p/11801564.html