python 协程
2019-08-24 本文已影响0人
落羽归尘
python 协程
生成器转协程
先看下面例子,我们根据此例子分析:
>>> def test():
... print("start")
... x = yield
... print("x: %s" % x)
... y = yield x
... print("end")
... print("y: %s" % y)
...
>>> g=test()
>>> next(g)
start
>>> g.send(3)
x: 3
3
>>> g.send(6)
end
y: 6
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
- 首先,test是我们定义的一个生成器,定义体必须要有yield关键字,这个生成器可以当成协程使用。
- 调用send方法前,必须调用一次next方法,对协程进行激活。
- 第一次调用next时,碰到yield会停止
- send(3)方法可以发送值给yield,x=yield也就是将x赋值为3,并且继续执行到下一个yield,而y = yield x,yield后面有x,会被当成类似return x打印出来
- send(6) 会发送值给y,继续执行到下一个yield,而这时没有了,就会抛出StopIteration异常。
我们用一个例子通过协程的方式求移动平均值:
def averager():
total = 0.0
count = 0
average = None
while True:
term = yield average
total += term
count += 1
average = total/count
ave=averager()
next(ave)
print(ave.send(2))
print(ave.send(3))
print(ave.send(4))
print(ave.send(5))
输出结果:
2.0
2.5
3.0
3.5
可以调用ave.close()方法终止协程。
yield from
yield from 简化了for循环的yield表达式:
def gen():
for i in range(3):
yield i
# 等同于
def gen_new():
yield from range(3)
print(list(gen()), list(gen_new()))
输出结果:
[0, 1, 2] [0, 1, 2]
gen等同于gen_new。yield from后面跟可迭代对象x。因为yield from x会调用iter(x)。