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()
来源: http://www.bubuko.com/infodetail-3257901.html