首页 > 代码库 > python yield 生成器

python yield 生成器

一。深入研究

>>> def get_0_1_2():...   yield 0...   yield 1...   yield 2...>>> get_0_1_2<function get_0_1_2 at 0x00B2CB70>       #函数类型>>> generator = get_0_1_2()>>> generator<generator object get_0_1_2 at 0x00B1C7D8>  #生成器>>> generator.next()    #第一次调用生成器的next方法时,生成器才开始执行生成器函数(而不是构建生成器时),直到遇到yield时暂停执行0>>> generator.next()    #之后每次调用生成器的next方法,生成器将从上次暂停执行的位置恢复执行生成器函数,直到再次遇到yield时暂停1>>> generator.next()2

>>> generator.next() #当调用next方法时生成器函数结束(遇到空的return语句或是到达函数体末尾),则这次next方法的调用将抛出StopIteration异常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

因为直接调用next()到最后会抛出异常,所以一般使用for循环输出结果

 

>>> def test_return():...      yield 4...      return 0...  File "<stdin>", line 3SyntaxError: return with argument inside generator

  作为生成器,因为每次迭代就会返回一个值,所以不能显示的在生成器函数中return 某个值,包括None值也不行,否则会抛出“SyntaxError”的异常,

但是在函数中可以出现单独的return,表示结束该语句。

 

二。示例

1.斐波那契数列

>>> def fibonacci():...   a = b = 1...   yield a...   yield b...   while True:...     a, b = b, a+b...     yield b...>>> for num in fibonacci():...   if num > 100: break...   print num,...1 1 2 3 5 8 13 21 34 55 89

看到while True可别太吃惊,因为生成器可以挂起,所以是延迟计算的,无限循环并没有关系。

 

2.读大文件

如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。

def read_file(path):    size = 1024    with open(path,r) as f:        while True:            block = f.read(SIZE)            if block:                yield block            else:                return

 

python yield 生成器