协程的运行一般是无限期的,使用方法close()可以显式的关闭它。
如果yield表达式中提供了值,协程可以使用yield语句同时接收和发出返回值。
def split_line():
print 'ready to split'
result=None
while True:
line=yield result
result=line.split()
>>> s=split_line()
>>> s.next()
ready to split
>>> s.send('1 2 3')
['1', '2', '3']
>>> s.send('a b c')
['a', 'b', 'c']
注意:理解这个例子中的先后顺序非常重要。首个next()方法让协程执行到yield result,这将返回result的值None。在接下来的send()调用中,接收到的值被放到line中并拆分到result中。send()方法的返回值就是下一条yield语句的值。也就是说,send()方法可以将一个值传递给yield表达式,但是其返回值来自下一个yield表达式,而不是接收send()传递的值的yield表达式。
如果你想用send()方法来开启协程的执行,必须先send一个None值,因为这时候是没有yield语句来接受值的,否则就会抛出异常。
>>> s=split_line()
>>> s.send('1 2 3')
TypeError: can't send non-None value to a just-started generator
>>> s=split_line()
>>> s.send(None)
ready to split
使用生成器与协程
乍看之下,如何使用生成器和协程解决实际问题似乎并不明显。但在解决系统、网络和分布式计算方面的某些问题时,生成器和协程特别有用。实际上,yield已经成为Python最强大的关键字之一。
比如,要建立一个处理文件的管道:
import os,sys
def default_next(func):
def start(*args,**kwargs):
f=func(*args,**kwargs)
f.next()
return f
return start
@default_next
def find_files(target):
topdir=yield
while True:
for path,dirname,filelist in os.walk(topdir):
for filename in filelist:
target.send(os.path.join(path,filename))
@default_next
def opener(target):
while True:
name=yield
f=open(name)
target.send(f)
@default_next










