阐述生成器里头send()以及next()方法的运用诀窍, 深度剖析二者区别还有实际运用情形。
1、 有一种基础实现方式即为处于异步IO编程里的生成器。生成器会提供出两个核心方法, 分别是send和next, 它们于控制生成器执行流程这个方面起着关键方面。当调用生成器之际, 开始使用next方法会启动生成器的运行程序, 该程序会从函数起始地方开始执行, 一直到碰到第一个yield语句形成暂停, 并且返回对应的值。到这个时候, 生成器便处于挂起状态。一旦下回调用next之际, 执行流程会自上回yield语句的后续代码起始进而不断往下推行, 一直持续到再度碰到yield为止, 这样循环往复, 营造出一种分段开展施行的效应。而send方法除了拥有类似next的效能之外, 还能够朝着生成器内部辗转递传资料, 达成方向相反的双向通信互联。凭借轮换运用这两个方法来进行操作, 能够精确无误地把控生成器的运行步调节奏, 致使其于异步任务开展调度、协程进行处理等相关事例情境当中展现出强劲有力的灵活性, 从而为搭建构建高效能的异步程序予以支撑辅助提供助力。
2、 以生产者-消费者模型为例,说明多线程协作机制。
3、 在功能方面, next()与send()方法有着一定程度的相似之处, 然而二者是存在关键区别的。主要的差异在于, send()方法可允许朝着生成器里的yield表达式传递一个具体的数值, 而next()方法仅仅能够隐式地传入None。所以, 调用C.next()实际上就等同于调用C.send(None)。当首次启动生成器之际, 得使用 next() 或者 send(None), 此二者不可偏废, 绝不能径直使用 send 传入非空值, 不然的话就会引发异常。推究其原因乃在于, 生成器还尚未启动运行, 根本不存在能够接收传入值的 yield 表达式去处理该数据。
4、 对于执行流程而言, 要明确的一点是, 像 N1 = yield R 这样的语句, 它是依照从右到左的顺序来开展求值动作的。在首次调用 send(None)(此对应代码第11行)之际, 生成器会被激活, 程序会从生成器函数的第一行起始执行, 一直延续到碰到第一个 yield 语句(比如说第4行)进而暂停。在这个时候, 鉴于赋值操作尚未完成, 变量 N1 还没有被绑定任何的值。
5、 当后续进行 send(1) 调用时, 控制权会重新进入生成器函数。这时, 当前传入值 1 被系统赋给 yield 表达式左边的变量 N1, 就如同执行了 N1 = 1 这个操作, 然而不会再次执行 yield R 的产出动作。在赋值做完以后, 程序会基于上次暂停位置其接下来那一条语句起始继续执行, 一直间断于再次碰到 yield 语句之时并返回对应成果。整个过程所呈现出来的情况是, 相较于next()而言, send()的核心额外操作仅仅是针对向yield左侧的变量进行赋值这一行为, 除此之外, 其余的执行方面的逻辑以及流程控制方面都是完全一样的。
6、 执行结果:
7、 生成器可通过函数或表达式创建
中关村在线所给出的分享生成器里, send()以及next()方法的运用技巧, 对两者之间的差异以及实际运用场景展开深入剖析。其一, 于异步IO编程范畴内, 生成器属于一种基础的实现形式。在此当中的生成器给出了两个核心方法: send以及next, 它们在对生成器执行流程进行控制这件事情上起着关键作用。当调用生成器之际, 首次运用next方法会。