一。深入研究
>>> 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 3 SyntaxError: ‘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
时间: 2024-10-28 23:07:51