日期:20170926
本次运行环境Python3
我们先来看一下代码,
#!/usr/bin/python3
def MyGenerator():
yield 1
yield 2
yield 3
return "done"
print(MyGenerator)
print()
Num=MyGenerator()
print(Num)
print(next(Num))
print(next(Num))
print(next(Num))
运行,
[penx@ali01 python2]$ ./example_generator.py
<function MyGenerator at 0x7f297bff99d8>
<generator object MyGenerator at 0x7f297bf57708>
1
2
3
[penx@ali01 python2]$
运行过程,
先print出MyGenerator的信息,可以看出它只是一个函数。
再调用MyGenerator,返回给Num。虽然MyGenerator是函数,但这里并没有执行。好戏在后头。
我print出Num的信息,却是一个“generator object”。调用一个函数不但没有执行,反而返回了一个对象,generator object。对象通常可以理解为实例。
很奇怪,对吧?Python把生成器的信息标志为函数(function),但调用时却生成一个实例。有可能Python把函数解析封装成一个生成器。
用next(Num)开始执行生成器函数,执行到yield 1时,返回并返回n。
再next,就会再次进入生成器函数,但并不是重头执行,而是上一次的yield 1后。遇到yield 2,再次返回。
再next,情况类似。
如果再加一个next,就会报StopIteration。
剖析,
其实yield并不神秘,其实就是我们学习操作系统时,任务挂起的知识点。
函数通过yield自己挂起,然后我们可以用next来唤醒它。
因为yield挂起时,会保存运行环境,所以next就可以知道函数运行到哪一步。