yield

yield是在定义生成器时使用,只能在函数体内使用,使得该函数变成一个生成器函数而不是普通的函数,然后该函数在调用时会返回生成器。

生成器像是个协程,多次yield,有多个进入点,执行会被暂停。但是生成器函数只要在调用了yield之后就不能再控制是否可继续执行,控制权就交给调用者了。

用于控制生成器的函数

generator.next()

启动执行一个生成器或恢复执行它

当生成器恢复的时候,当前的yield产生的值就变成空了,生成器继续执行,再yield一个值,则这个值就被返回给调用者了,不yield同时生成器结束执行则抛出[StopIteration]

generator.send(value)

恢复执行并把value发送到生成器函数中

value值就变成当前的yield产生的值,生成器继续执行,再yield一个值,则这个值就被返回给调用者了,不yield同时生成器结束执行则抛出[StopIteration],如果是使用send方式来启动一个生成器则参数虚伪None,因为没有所谓的当前yield产生的值来接收它。

generator.throw(type[, value[, traceback]])

在生成器当前暂停的地方抛出异常,type为异常的种类,并把下一个生成器产生的值yield出,如果生成器退出了并没有yield值,那么会抛出StopIteration,如果生成器中没有捕获异常或抛出了不同的异常,那么该异常会衍生到调用者。

generator.close()

在生成器当前暂停的地方产生 [GeneratorExit]异常。

如果生成器抛出[StopIteration](正常结束或已经被关闭时)或者[GeneratorExit](生成器中没有捕获异常的操作所以直接衍生给调用者),则控制权返回给调用者,如果此时生成器yield一个值会造成[RuntimeError],如果抛出的是其他异常,也会衍生到调用者。如果生成器已经结束了则不会造成任何影响。

If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller.

>>> def echo(value=None):
...     print "Execution starts when 'next()' is called for the first time."
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception, e:
...                 value = e
...     finally:
...         print "Don't forget to clean up when 'close()' is called."
...
>>> generator = echo(1)
>>> print generator.next()
Execution starts when 'next()' is called for the first time.
1
>>> print generator.next()
None
>>> print generator.send(2)
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.

优势

线程极高的执行效率,没有线程切换开销,不加锁,通过多进程+协程利用多核CPU。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容