下面的代码演示了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()
参考:
7. Input and Output in The Python Tutorial