coroutine和generator的区别
generator是数据的产生者。即它pull data 通过 iteration
coroutine是数据的消费者。它push data into pipeline 通过 send
generator通常用法
generator的作用是可以作为data pipeline使用
例如:可以使用coroutine来做filter或者多路的broadcast,generator通常是yield和for的运用,如:
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a+b
for i in fib():
print(i)
用yield接收data,通过for循环将每一步data输出
coroutine它的yield接收外部value,而不是保存内部value
def grep(pattern):
print("Searching for", pattern)
while True:
line = (yield)
if pattern in line:
print line
先通过next(),start这个coroutine
之后每一次调用send(),将参数通过yield传入line中。同时相当于自动运行.next()到下一个value. 最终调用.close()关闭这个协程
实例:filter作用
import time
def follow(thefile, target):
thefile.seek(0,2) # Go to the end of the file
while True:
line = thefile.readline()
if not line:
time.sleep(0.1) # Sleep briefly
continue
target.send(line)
def printer():
while True:
line = (yield)
print line
def grep(pattern,target):
while True:
line = (yield) # Receive a line
if pattern in line:
target.send(line) # Send to next stage
f = open("access.log")
follow(f,grep('error',printer()))
dataflow如下:
follow将file中的每一行读取,send到coroutine中,grep查找匹配的line,send到下一个coroutine中,printer接收send过来的data,并且输出, 完成整个filter的流程
follow()-> grep() : send()
grep() -> printer():send()
实例:broadcasting作用
def broadcast(targets):
while True:
item = (yield)
for target in targets:
target.send(item)
f = open("access-log")
p = printer()
follow(f,
broadcast([grep('python',p),
grep('ply',p),
grep('swig',p)])
)
这样就将不同的pattern传入到了不同的coroutine中去,达到了broadcast的目的
follow-> broadcast: send()
broadcast -> grep('python'): send()
broadcast -> grep('ply') : send()
broadcast -> grep('swig') : send()
grep('python') -> printer:
grep('ply')-> printer:
grep('swig')-> printer:
关于coroutine的更多用法:
http://www.dabeaz.com/coroutines/Coroutines.pdf