Using Return and Yield Together in Python Generators
In Python 2, a return statement inside a generator function that also used yield would result in an error. However, in Python 3.3, a subtle change occurred.
Code Demonstration
Consider the following Python 3.3 code:
<code class="python">def f(): return 3 yield 2 x = f() print(x.__next__())</code>
Explanation
In this code, the function f includes both a return statement and a yield statement. When the function is called, the return statement is executed first, and the value 3 is returned. As a result, the yield statement is not executed.
When the generator x is iterated by calling its next method, a StopIteration exception is raised with a value of 3. This means that the generator's iterator is exhausted, and the value returned by the return statement is available as the value attribute of the exception.
New Mechanism in Python 3.3
According to PEP 380, this behavior is a new feature introduced in Python 3.3. It is equivalent to writing:
<code class="python">def f(): yield 3 raise StopIteration</code>
Example with Yield from
The following example demonstrates how this behavior affects generators delegated using the yield from syntax:
<code class="python">def f(): return 1 yield 2 def g(): x = yield from f() print(x) # g is still a generator so we need to iterate to run it: for _ in g(): pass</code>
In this case, the yield from statement delegates to the generator f. Since f returns a value but has no more yield statements, the value 1 is printed. However, the yield 2 statement in f is not executed.
The above is the detailed content of How Do Return and Yield Work Together in Python 3.3 Generators?. For more information, please follow other related articles on the PHP Chinese website!