《Python参考手册(第4版•修订版)》——1.13 协程

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

《Python参考手册(第4版•修订版)》——1.13 协程的相关文章

《Python参考手册(第4版•修订版)》——导读

前 言 本书是Python编程语言的一份简明参考.尽管有经验的程序员也可以通过本书学习Python语言,但本书并不是一本讲述如何编程的全面教程或专著.相反,本书的目标是准确而简练地介绍Python语言核心以及Python库中最关键的部分.本书假定读者以前拥有Python或其他语言(如C或Java)的编程经验.另外,对系统编程(例如基本的操作系统概念和网络编程)有大致的了解对理解Python库参考中的部分章节可能会有一定的帮助. 本书的这一版是在Python发展的关键时刻面世的.Python 2.

《Python参考手册(第4版•修订版)》——第一部分 Python语言 第1章 Python简介 1.1 运行Python

第一部分 Python语言 本部分内容 第1章 Python简介 第2章 词汇和语法约定 第3章 类型与对象 第4章 运算符与表达式 第5章 程序结构与控制流 第6章 函数与函数编程 第7章 类与面向对象编程 第8章 模块.包与分发 第9章 输入与输出 第10章 执行环境 第11章 测试.调试.探查与调优 第1章 Python简介 本章将快速介绍Python这门语言,目标是在阐明Python的大部分基本特性的同时,又不会太过纠缠于特殊的规则或细节.为此,本章简要讲述一些基本概念,如变量.表达式.

《Python参考手册(第4版•修订版)》——2.4 字符串字面量

2.4 字符串字面量 字符串字面量用于指定一个字符序列,其定义方法是把文本放入单引号(').双引号(")或三引号('''或""")中.这三种引号形式在语义上没有差别,但要求在字符串开始和结尾使用的引号类型必须相同.置于单引号和双引号中的字符串必须定义在一行上,而三引号的字符串可以分布在多行上,并且会将所有格式符号(即换行符.制表符.空格等)包含在内.像"hello" 'world'这样的相邻字符串(由空格.换行符或续行符隔开)将被连接起来,形成一

《Python参考手册(第4版•修订版)》——1.10 迭代与循环

1.10 迭代与循环 最常用的循环结构是for语句,它可以用来对容器成员进行迭代操作.迭代是Python中内涵最丰富的功能之一.但最常见的迭代形式是简单循环访问一个序列(如字符串.列表或元组)的所有成员,例如: for n in [1,2,3,4,5,6,7,8,9]: print "2 to the %d power is %d" % (n, 2**n) 在这个例子中,每次迭代都会将列表[1,2,3,4,...,9]中的下一个值赋给变量n.因为在整数范围内执行循环十分常见,为此经常会

《Python参考手册(第4版•修订版)》——1.9 字典

1.9 字典 字典就是一个关联数组或散列表,其中包含通过键(key)索引的对象.在大括号({ })中放入值即可创建字典,如下所示: stock = { "name" : "GOOG", "shares" : 100, "price" : 490.10 } 要访问字典成员,可使用键索引运算符,如下所示: name = stock["name"] value = stock["shares"

《Python参考手册(第4版•修订版)》——1.6 列表

1.6 列表 列表是任意对象组成的序列.把值放入方括号中就可以创建列表,如下所示: names = [ "Dave", "Mark", "Ann", "Phil" ] 列表使用从0开始的整数索引,使用索引运算符可以访问并修改列表中的项: a = names[2] # 返回列表的第3项"Ann" names[0] = "Jeff" # 将第1项改为"Jeff" 要将新项

《Python参考手册(第4版•修订版)》——1.4 文件输入和输出

1.4 文件输入和输出 以下程序可打开一个文件并逐行读取该文件的内容: f = open("foo.txt") # 返回一个文件对象 line = f.readline() # 调用文件的readline()方法 while line: print line, # 后面跟','将忽略换行符 # print(line,end='') # 在Python 3中使用 line = f.readline() f.close() open()函数返回一个新的文件对象.调用该对象的方法可以执行各种

《Python参考手册(第4版•修订版)》——1.5 字符串

1.5 字符串 要创建一个字符串字面量,将字符串放在单引号.双引号或三引号中即可,如下所示: a = "Hello World" b = 'Python is groovy' c = """Computer says 'No'""" 字符串前后使用的引号必须是对应匹配的.两个三引号之间出现的所有文本都视为字符串的内容,而使用单引号和双引号指定的字符串必须在一个逻辑行上.当字符串字面量的内容需放在多个文本行上时,三引号字符串就很

《Python参考手册(第4版•修订版)》——1.12 生成器

1.12 生成器 如果使用yield语句,可以让函数生成一个结果序列,而不仅仅是一个值,例如: def countdown(n): print "Counting down!" while n > 0: yield n # 生成一个值(n) n -= 1 任何使用yield的函数都称为生成器.调用生成器函数将创建一个对象,该对象通过连续调用next()方法(在Python 3中是__next__())生成一系列的结果,例如: >>> c = countdown(