Python协程(coroutine)

Admin 2018-07-11 16:51:03 Django

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

相关文章
最新推荐