DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

Python的Generator和yield


下面的代码演示了yield的一个使用场景:

def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b 
        # print b 
        a, b = b, a + b 
        n = n + 1

for n in fab(5):
    print(n)

简单地讲,yield的作用就是把一个函数变成一个Generator, 带有yield的函数不再是一个普通函数,Python解释器会将其视为一个Generator, 调用fab(5)不会执行fab函数,而是返回一个iterable对象。 在for循环执行时,每次循环都会执行fab函数内部的代码,执行到yield b时, fab 函数就返回一个迭代值,下次迭代时,代码从yield b的下一条语句继续执行, 而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行, 直到再次遇到yield。

上面的fab函数也可以返回一个List,与Generator相比,缺点是内存使用量会很大, 比如要读取一个10GB的文件,如果直接使用f.read()会把整个文件加载到内存中, 用Generator代替List,可以保证内存使用量是固定的,例如下面的1024字节:

def read_file(fpath): 
    BLOCK_SIZE = 1024 
    with open(fpath, 'rb') as f: 
        while True: 
            block = f.read(BLOCK_SIZE) 
            if block: 
                yield block 
            else: 
                return

上面的文件读取是为了演示yield的用法,在实际读取文件时, 如果是大文件,不能一次性载入所有内容,使用for循环,一次载入一行到内存:

with open('workfile', 'r') as f:
    for line in f:
        print(line)

反之,如果文件比较小,需要一次性载入内存,使用readlines()方法:

with open('workfile', 'r') as f:
    lines = f.readlines()

参考:

Python yield 使用浅析

7. Input and Output in The Python Tutorial



Published

Apr 8, 2015

Last Updated

Apr 8, 2015

Category

Tech

Tags

  • generator 2
  • python 136
  • yield 2

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor