搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > 我爱学Python > Python — yield from 的意义

Python — yield from 的意义

我爱学Python 2017-10-30

一、背景

“For humans, almost all the important information is contained in one paragraph near the top.” — Greg Ewing

yield from 的草案发布于 PEP380, 当时提出这个草案的时候,许多人提出了关于语法过于复杂的质疑,但是 Greg Ewing 用上面这句话正面回应了这些质疑。

以上引用的大致意思是:“对于人类而言,几乎所有重要的信息都包含于靠近顶部的那一个段落里。”,对于曾经做过无数阅读理解的中国人健儿们而言,“第一段点明中心”,相信各位再熟悉不过了。

“When the iterator is another generator, the effect is the same as if the body of the subgenerator were inlined at the point of the yield from expression. Furthermore, the subgenerator is allowed to execute a return statement with a valu

以上是 Greg Ewing 引用 PEP380 中的一个段落。

以上引用的大致意思是:“当迭代器是另一个生成器时,效果看上去就好像子生成器的代码体在 yield from 表达式所在的位置一样。此外,子生成器也允许执行一个 带有值的return 语句,并且那个值会成为 yield from 表达式的值。”

当然,这句话在 PEP 中已经做过一定的修改,因为它并没有包含所有的情况,不过这依然体现了 Greg Ewing 在设计这个语法的时候的初衷。

二、6 个行为要点

  • 子生成器产生的任何值都是直接传递给代理生成器的调用者(客户代码)的

  • 实用 send 发送给代理生成器的任何值都会直接传递给子生成器

  1. 如果发送的值是 None,那么子生成器的 __next()__ 被调用。

  2. 如果发送的值不是 None,那么子生成器的 send() 方法被调用。

  3. 如果调用引发了一个 StopIteration,那么代理生成器被恢复。

  4. 如果调用引发了其他的异常,那么这些异常都会传播到代理生成器中。

  • 生成器中的 return expr 会使得 StopIteration(expr) 在生成器退出的时候被引发

  • yield from 表达式的值是子生成器在结束时引发的 StopIteration 异常的第一个参数

  • 被抛入到代理生成器中的除了 GeneratorExit 以外的异常,会传递到子生成器的 throw() 方法。就像通过调用使得子生成器发生了异常一样。

  • 如果 GeneratorExit 异常被抛入到代理生成器,或者代理生成器的 close() 方法被调用,那么

    1. 当子生成器有 close() 方法时,close() 方法被调用

    2. 如果这个调用导致了一个异常,那么会传播至代理生成器

    3. 其他情况下,会在代理生成器中引发一个 GeneratorExit 异常

    三、意义

    在基于 yield from 语法的引入后,我们可以更加自然的表达许多的算法。特别是一下几类尤为突出:

    • 模拟

    • 游戏

    • 事件驱动

    • 其他形式的协作多任务

    四、离散事件模拟中的意义

    离散事件模拟(DES / discrete event simulation)是模拟的其中一类,它的系统被建模为时间序列。

    在离散事件模拟中,模拟时钟不会以固定的增量变化,而是直接进入下一个建模事件的模拟时间。

    在这种模式下,非常适合使用 yield from 来提供生成器代理,将协程绑定在事件循环中,实现基于事件循环的并发。著名的 Twisted 和 Tornado 就利用了这一机制。

    最为常见的案例,就是回合制游戏的内部机制。

    五、与时时模拟的区别

    与离散模拟对应的也就是时时模拟,时时游戏就是如此。此时我们更应该实用多线程来处理这类事件模拟。因为生成器并不能很好的抽象此类逻辑。

    六、现实意义

    对于那些做手游服务器后端的人来说,特别适合参考本文中所提到的技术,深入研究可以使得后台的性能获得较大的提升。


版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《Python — yield from 的意义》的版权归原作者「Python热爱者」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注Python热爱者微信公众号

Python热爱者微信公众号:Python-520

Python热爱者

手机扫描上方二维码即可关注Python热爱者微信公众号

Python热爱者最新文章

精品公众号随机推荐