<p><a href="https://docs.python.org/3.5/reference/simple_stmts.html#the-yield-statement"><em>yield</em></a>语句类似于<em>return</em>返回值,但它不会破坏堆栈帧(函数中知道当前行、局部变量和挂起的try语句的部分)。这样就可以在屈服后恢复函数。在</p>
<p>当您调用一个包含yield的函数时,它返回一个<a href="https://docs.python.org/3.5/glossary.html#term-generator">"generator"</a>,它允许您运行代码到一个yield,然后从它停止的地方恢复它。在</p>
<pre><code>>>> def squares(n):
for i in range(n):
yield i ** 2
>>> g = squares(5) # create the generator
>>> g
<generator object squares at 0x106beef10>
>>> next(g) # run until the first yield
0
>>> next(g) # resume after the yield
1
>>> next(g) # resume after the yield
4
>>> next(g) # resume after the yield
9
>>> next(g) # resume after the yield
16
>>> next(g) # looping is terminated with a StopIteration
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
next(g) # looping is terminated with a StopIteration
StopIteration
</code></pre>
<p>有趣的是,生成器可以使用<em>send()</em>方法接受值。要为这种发生器启动泵,第一个调用应该是<em>next()</em>。在</p>
^{pr2}$
<p>在您的示例中,您发现<code>next(g)</code>实际上与{<cd2>}相同。在</p>
<p>以下是<a href="https://docs.python.org/3.5/reference/expressions.html#yield-expressions">the docs</a>要说的:</p>
<blockquote>
<p>The value of the yield expression after resuming depends on the method
which resumed the execution. If __next__() is used (typically via
either a for or the <em>next()</em> builtin) then the result is <em>None</em>.
Otherwise, if <em>send()</em> is used, then the result will be the value passed
in to that method</p>
</blockquote>
<p>下面是一个让所有这些都可见的会话:</p>
<pre><code>>>> def show_expression():
for i in range(5):
word = yield 10
print('The word is %r' % word)
>>> g = show_expression()
>>> next(g)
10
>>> g.send('blue')
The word is 'blue'
10
>>> g.send('no')
The word is 'no'
10
>>> g.send('yellow')
The word is 'yellow'
10
>>> next(g)
The word is None
10
>>> g.send('done')
The word is 'done'
Traceback (most recent call last):
File "<pyshell#44>", line 1, in <module>
g.send('done')
StopIteration
</code></pre>
<p>希望能解释第一原则中所有的谜团:-)</p>