1、复习
def generator(): print('1') yield 'a' print('2') yield 'b' print('3') g = generator() res = g.__next__() # 第一个__next__执行到第一个yiled停止, 并返回第一个yiled处的值 print(res) res = g.__next__() # 第二个__next__执行到第二个yiled停止, 并返回第二个yiled处的值 print(res) res = g.__next__() # 虽然执行了print('3')操作,但是报错,因为后续没有yiled了,为了避免报错,可以结尾加上yiled print(res)
2、send
def generator(): print('1') num = yield 'a' # 此处如果继续执行,使用__next__触发,num将会被复制None。使用send,num将会接收seed的值 print("seed num:%s" % num) print('2') yield num * 2 print('3') yield g = generator() res = g.__next__() # 第一个__next__执行到第一个yiled停止, 并返回第一个yiled处的值 print(res) res = g.send(10) # 发送值给生成器内部,并返回下一个yiled处的值 print(res) res = g.__next__() # 虽然执行了print('3')操作,但是报错,因为后续没有yiled了,为了避免报错,可以结尾加上yiled print(res) # 由于yield没有返回值,返回None
- send的获取下一个值得能力和next一致。
- send时,传递值给当前send位置的yield,并执行代码带一个yiled处停止
- 使用send注意事项:
- 第一次获取生成器的值时,使用next,不能以开始就是用send
- 最后一个yiled的位置,不能使用send,否则会报错“StopIteration”
3、yield from
yiled from 可以从生成器函数中,依次返回各个值
def func(): s = 'abcd' num = '1234' yield from s yield from num for i in func(): print(i)
X、练习
# 获取移动平均值 def move_arg(): sum = 0 count =0 avg = 0 while 1: num = yield avg sum += num count += 1 avg = sum / count g = move_arg() print(g.__next__()) print(g.send(10)) print(g.send(20)) print(g.send(30)) print(g.send(10))
使用装饰器,完善上述代码,是代码,使代码运行更加顺畅
def init(f): def warp(): g = f() # 调用生成器函数,得到一个生成器 g.__next__() # 预激活,执行next return g # 返回激活器 return warp @init def move_arg(): sum = 0 count =0 avg = 0 while 1: num = yield avg sum += num count += 1 avg = sum / count g = move_arg()