<p>当您在生成器中使用<code>send</code>和表达式<code>yield</code>时,您将其视为一个协程;一个单独的执行线程,可以按顺序交错运行,但不能与其调用方并行。</p>
<p>当调用方执行<code>R = m.send(a)</code>时,它将对象<code>a</code>放入生成器的输入槽中,将控制权传递给生成器,并等待响应。生成器接收作为<code>X = yield i</code>结果的对象<code>a</code>,并运行,直到它碰到另一个<code>yield</code>表达式,例如<code>Y = yield j</code>。然后它将<code>j</code>放入其输出槽,将控制权传输回调用方,并等待它再次恢复。调用者接收<code>j</code>作为<code>R = m.send(a)</code>的结果,并一直运行,直到它碰到另一个<code>S = m.send(b)</code>语句,依此类推。</p>
<p><code>R = next(m)</code>与<code>R = m.send(None)</code>一样;它将<code>None</code>放入生成器的输入槽中,因此如果生成器检查<code>X = yield i</code>的结果,那么<code>X</code>将是<code>None</code>。</p>
<p>作为一个隐喻,考虑一个<a href="http://www.flickr.com/photos/duncan/7458208/" rel="noreferrer">dumb waiter</a>:</p>
<p><img src="https://i.stack.imgur.com/OZXte.jpg" alt="Dumb waiter"/></p>
<p>当服务生接到顾客的订单时,他们把便笺簿放进哑服务生的房间,然后把便笺簿放进厨房,在舱口等菜:</p>
<pre><code>R = kitchen.send("Ham omelette, side salad")
</code></pre>
<p>厨师(一直在舱口旁边等着)拿起订单,准备好菜,把它送到餐厅,然后等待下一个订单:</p>
<pre><code>next_order = yield [HamOmelette(), SideSalad()]
</code></pre>
<p>服务员(一直在舱口等着)把菜拿给顾客,然后拿着另一份订单等回来</p>
<p>因为服务器和厨师在点餐或上菜后都在舱口等候,所以在同一时间只有一个人在做任何事情,也就是说,这个过程是单线程的。双方可以使用正常的控制流程,因为发电机机械(哑服务员)负责交织执行。</p>