1.13 协程
通常,函数运行时要使用单一的一组输入参数。但是,函数也可以编写成一个任务程序, 用来处理发送给它的一系列输入。这类函数被称为协程,它是通过将yield语句作为表达式(yield)的形式创建的,如下所示:
def print_matches(matchtext):
print "Looking for",matchtext
while True:
line = (yield) # 获得一行文本
if matchtext in line:
print line
要使用这个函数,首先要调用它,向前执行到第一条(yield)语句,然后使用send()给它发送数据,例如:
>>> matcher = print_matches("python")
>>> matcher.next() # 向前执行到第一条(yield)语句
Looking for python
>>> matcher.send("Hello World")
>>> matcher.send("python is cool")
python is cool
>>> matcher.send("yow!")
>>> matcher.close() # matcher函数调用结束
>>>
使用send()为协程发送某个值之前,协程会暂时中止。发送值之后,协程中的(yield)表达式将返回这个值,而接下来的语句将会处理它。处理直到遇到下一个(yield)表达式才会结束,这时函数将暂时中止。正如上一个例子所示,这个过程将会继续下去,直到协程函数返回或者调用它的close()方法为止。
基于生产者—消费者模型(即程序的一部分生成的数据会被程序的另一部分使用)编写并发程序时,协程十分有用。在这种模型中,协程代表了数据的一个消费者。下面给出了一起使用生成器和协程的一个例子:
# 一组匹配器协程
matchers = [
print_matches("python"),
print_matches("guido"),
print_matches("jython")
]
# 通过调用next()准备所有的匹配器
for m in matchers: m.next()
# 将一个活跃的日志文件传递给所有的匹配器。注意,为保证运行正常,
# 必须有一台Web服务器持续将数据写入日志
wwwlog = tail(open("access-log"))
for line in wwwlog:
for m in matchers:
m.send(line) # 将数据发送到每个匹配器协程中
第6章将会进一步介绍协程。
时间: 2024-12-24 20:51:16