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

    xiaoxiao2024-10-07  75

    本节书摘来自异步社区《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中插入不同对象,为创建可扩展的程序提供了一个强大的工具。

    相关资源:Python参考手册(第4版•修订版)
    最新回复(0)