生成器进阶

send()的获取下一个值的效果和__next__一致,

特别:在获取下一个值的时候,给上一个值的位置传递一个数据

 

def generator():
    print(123)
    content = yield 1 # 返回1,赋值来不及,send传了一个值给content
    print('===',content)
    print(456)
    yield 2

g = generator() # 知道是生成器,啥也不执行
ret = g.__next__() # 开始执行,print(123)执行,yield 1返回给ret
print('***',ret) #打印1
ret = g.send('hello') # 继续执行生成器,在执行之前,yield 1变成了hello,注意继续执行到yield 2,2给了ret
print('***',ret)

 注意:

第一次使用生成器的时候,用next获取下一个值(因为没有yield)

最后一个yield不能接受外部的值(错误:ret = yield 2)

 

获取移动平均值(如淘宝评价):

def average():
    sum1 = 0
    count = 0
    avg = 0
    num = yield
    sum1 += num
    count += 1
    yield sum1/count
avg_g = average()
avg_g.__next__()
avg_g.send(10)

 

# 优化算法
def average():
    sum1 = 0
    count = 0
    avg = 0
    while 1:
        num = yield avg
        sum1 += num
        count += 1
        avg = sum1/count

avg_g = average()
avg_g.__next__()
avg_g.send(10)
avg_g.send(20)
avg_g.send(30)

 预先激活生成器的装饰器:

def init(f):
    def inner(*args,**kwargs):
        g = f(*args,**kwargs)
        g.__next__()
        return g
    return inner
@init
def average():
    sum1 = 0
    count = 0
    avg = 0
    while 1:
        num = yield avg
        sum1 += num
        count += 1
        avg = sum1/count

avg_g = average()
ret = avg_g.send(10)
print(ret)
avg_g.send(20)
avg_g.send(30)

 

posted @ 2019-10-10 20:04  小然同学  阅读(105)  评论(0编辑  收藏  举报