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

本节书摘来自异步社区《Python参考手册(第4版•修订版)》一书中的第1章,第1.12节,作者David M. Beazley,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.12 生成器

如果使用yield语句,可以让函数生成一个结果序列,而不仅仅是一个值,例如:

def countdown(n):
    print "Counting down!"
    while n > 0:
         yield n       # 生成一个值(n)
         n -= 1

任何使用yield的函数都称为生成器。调用生成器函数将创建一个对象,该对象通过连续调用next()方法(在Python 3中是__next__())生成一系列的结果,例如:

>>> c = countdown(5)
>>> c.next()
Counting down!
5
>>> c.next()
4
>>> c.next()
3
>>>

next()调用使生成器函数一直运行,到下一条yield语句为止。此时next()将返回传递给yield的值,而且函数将暂时中止执行。再次调用next()时,函数将继续执行yield之后的语句。此过程持续到函数返回为止。

通常不会像上面这样手动调用next(),而是会使用一个for循环,例如:

>>> for i in countdown(5):
...     print i,
Counting down!
5 4 3 2 1
>>>

生成器是编写基于处理管道、流或数据流程序的一种极其强大的方式。例如,下面的生成器函数模拟了常用于监控日志文件的UNIX tail –f命令的行为:

# tail一个文件(如tail -f) 
import time
def tail(f):
    f.seek(0,2)     # 移动到EOF
    while True:
        line = f.readline()    # 尝试读取一个新的文本行
        if not line:           # 如果没有内容,暂时休眠并再次尝试
             time.sleep(0.1)
             continue
        yield line

下面的生成器用于在很多行中查找特定的子字符串:

def grep(lines, searchtext): 
    for line in lines:
        if searchtext in line: yield line

下面的例子将以上两个生成器合并在一起,创建了一个简单的处理管道:

# UNIX "tail –f | grep python"命令的python实现 
wwwlog = tail(open("access-log"))
pylines = grep(wwwlog,"python")
for line in pylines:
    print line,

生成器的微妙之处在于,它经常和其他可迭代的对象(如列表或文件)混合在一起。特别是在编写如for item in s这样的语句时,s可以代表一个列表、文件的各行、生成器函数的结果,或者支持迭代的其他任何对象。能够在s中插入不同对象,为创建可扩展的程序提供了一个强大的工具。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值