How does this python yield function work?
<pre class="lang-py prettyprint-override"><code>def func():
    output = 0
    while True:
        new = yield output
        output = new


genr = func()
print(next(genr))
print(next(genr))
print(next(genr))
</code></pre>

<p>output:</p>

<blockquote>
  <p>0<br>
  None<br>
  None  </p>
</blockquote>

<p>What i thought is:</p>

<ol>
<li><code>genr=func()</code> return a generator, but does not actually run it.</li>
<li>First <code>print(next(genr))</code> run from the begining of func to <code>yield output</code>, but not yet assign back to <code>new</code>,so output <code>0</code> make sense.  </li>
<li>Second <code>print(next(genr))</code> start from assigning <code>output</code> back to <code>new</code>ï¼and next line <code>output = new</code> make both <code>output</code> and <code>new</code> to 0, next execute <code>yield output</code> should return 0, but why it return <code>None</code> actually?</li>
</ol>

<p>A <a href="https://docs.python.org/3.5/reference/simple_stmts.html#the-yield-statement"><em>yield</em></a> statement is used like <em>return</em> to return a value but it doesn't destroy the stack frame (the part of a function that knows the current line, local variables, and pending try-statements).  This allows the function to be resumed after the yield.</p>

<p>When you call a function containing yield, it returns a <a href="https://docs.python.org/3.5/glossary.html#term-generator">"generator"</a> that allows you to run code up to a yield and then to resume it from where it left off.</p>

<pre><code>&gt;&gt;&gt; def squares(n):
        for i in range(n):
            yield i ** 2

&gt;&gt;&gt; g = squares(5)             # create the generator
&gt;&gt;&gt; g
&lt;generator object squares at 0x106beef10&gt;
&gt;&gt;&gt; next(g)                    # run until the first yield
0
&gt;&gt;&gt; next(g)                    # resume after the yield
1
&gt;&gt;&gt; next(g)                    # resume after the yield
4
&gt;&gt;&gt; next(g)                    # resume after the yield
9
&gt;&gt;&gt; next(g)                    # resume after the yield
16
&gt;&gt;&gt; next(g)                    # looping is terminated with a StopIteration
Traceback (most recent call last):
  File "&lt;pyshell#13&gt;", line 1, in &lt;module&gt;
    next(g)                    # looping is terminated with a StopIteration
StopIteration
</code></pre>

<p>Interestingly, a generator can accept values using the <em>send()</em> method.  To prime the pump for such a generator the first call should be <em>next()</em>.</p>

<pre><code>&gt;&gt;&gt; def capitalize():
        word = 'start'
        while word != 'quit':
            word = yield word.capitalize()

&gt;&gt;&gt; g = capitalize()
&gt;&gt;&gt; next(g)                      # run to the first yield
'Start'
&gt;&gt;&gt; g.send('three')              # send in a value to be assigned to word
'Three'
&gt;&gt;&gt; g.send('blind')              # send in a value to be assigned to word
'Blind'
&gt;&gt;&gt; g.send('mice')               # send in a value to be assigned to word
'Mice'
&gt;&gt;&gt; g.send('quit')               # send in a control value
Traceback (most recent call last):
  File "&lt;pyshell#28&gt;", line 1, in &lt;module&gt;
    g.send('quit')               # send in a control value
StopIteration
</code></pre>

<p>What you've figured-out in your example is that <code>next(g)</code> is really the same as <code>g.send(None)</code>.</p>

<p>Here's what <a href="https://docs.python.org/3.5/reference/expressions.html#yield-expressions">the docs</a> have to say:</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>Here's a session that makes all of that visible:</p>

<pre><code>&gt;&gt;&gt; def show_expression():
        for i in range(5):
            word = yield 10
            print('The word is %r' % word)

&gt;&gt;&gt; g = show_expression()
&gt;&gt;&gt; next(g)
10
&gt;&gt;&gt; g.send('blue')
The word is 'blue'
10
&gt;&gt;&gt; g.send('no')
The word is 'no'
10
&gt;&gt;&gt; g.send('yellow')
The word is 'yellow'
10
&gt;&gt;&gt; next(g)
The word is None
10
&gt;&gt;&gt; g.send('done')
The word is 'done'
Traceback (most recent call last):
  File "&lt;pyshell#44&gt;", line 1, in &lt;module&gt;
    g.send('done')
StopIteration
</code></pre>

<p>Hope that explains all the mysteries from first principles :-)</p>

python yield