day15生成器进阶

复习

可迭代对象:元组,列表,字典,字符串,集合,range  可以加__iter__的一类

迭代器 = 同时含有__iter__ + __next__方法的  文件句柄就是一个

生成器  : 生成器就是迭代器 

生成器函数:函数中以yield结尾的

       作用:处理庞大的数据可以有限降低内存使用率。

生成器进阶

send 的用法,求取最近几天的平均数。

def average_func():
    average = 0
    count=0
    total = 0
    while True:
        value = yield average
        total += value
        count +=1
        average =total /count
g = average_func()
print(g.__next__())  #激活函数 
print (g.send(30))
print (g.send(40))

  首先可以看到average_func函数是个生成器函数,虽然调用了g = average_func()函数但是不会执行,首先是打印的g.__next__()函数可以调用函数返回一个值,此时已经激活函数,且在yield average处就绪,接着执行g.send(30),此时yield average变成30,也就是value=30,继续执行函数经过while循环到达 yield average,返回结果为30且在此处继续等待下次的执行命令。

进阶:

def wrapper(func):
    def inner(*args,**kwargs):
        g = func(*args,**kwargs)
        g.__next__()
        return g
    return inner
@wrapper #average_func =wrapper(average_func)
def average_func():
    average = 0
    count=0
    total = 0
    while True:
        value = yield average。
        total += value
        count +=1
        average =total /count
g = average_func()
print (g.send(30))
print (g.send(40))

  上面的是题目加上了一个“”生成器预激装饰器“”

首先是定义装饰器函数,经过@wrapper,也就是average_func=wrapper(average_func),先执行wrapper(average_func)函数,定义了一个inner()函数且返回inner也就是average_func = inner,继续向下执行定义了生成器average_func()函数,向下执行到g =average_func(),因为average_func = inner所有调用了inner函数,执行inner函数,在函数中g就是一个生成器,执行g.__next__就执行了生成器函数,此时函数运行走到了yield average处,等待下次执行send运算,生成器函数执行结束,return 预激的生成器给定义的生成器函数。此时利用装饰器完成预激,g是生成器的对象,直接使用send 就可以了。

首先:send和next工作的起止位置是完全相同的
# send可以把一个值作为信号量传递到函数中去
# 在生成器执行开始,只能先用next
# 只要用send传递参数的时候,必须在生成器中还有一个未被返回的yield

 

 

 

posted @ 2017-09-05 20:19  hello沃德  阅读(56)  评论(0)    收藏  举报