summaryrefslogtreecommitdiffstats
path: root/Doc/whatsnew
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2012-03-06 12:31:12 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2012-03-06 12:31:12 (GMT)
commitb9b281b78787a63a86d865bdcb8e7aad36d09e19 (patch)
treee628a48ee21e36fff797280ae57cb3b76aa90581 /Doc/whatsnew
parent98e20701cb30fbff0e49866d643aa540aff97e1f (diff)
downloadcpython-b9b281b78787a63a86d865bdcb8e7aad36d09e19.zip
cpython-b9b281b78787a63a86d865bdcb8e7aad36d09e19.tar.gz
cpython-b9b281b78787a63a86d865bdcb8e7aad36d09e19.tar.bz2
Add some simple examples to the PEP 380 section of What's New
Diffstat (limited to 'Doc/whatsnew')
-rw-r--r--Doc/whatsnew/3.3.rst47
1 files changed, 47 insertions, 0 deletions
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst
index f670362..23048c5 100644
--- a/Doc/whatsnew/3.3.rst
+++ b/Doc/whatsnew/3.3.rst
@@ -262,9 +262,56 @@ part of its operations to another generator. This allows a section of code
containing 'yield' to be factored out and placed in another generator.
Additionally, the subgenerator is allowed to return with a value, and the
value is made available to the delegating generator.
+
While designed primarily for use in delegating to a subgenerator, the ``yield
from`` expression actually allows delegation to arbitrary subiterators.
+For simple iterators, ``yield from iterable`` is essentially just a shortened
+form of ``for item in iterable: yield item``::
+
+ >>> def g(x):
+ ... yield from range(x, 0, -1)
+ ... yield from range(x)
+ ...
+ >>> list(g(5))
+ [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]
+
+However, unlike an ordinary loop, ``yield from`` allows subgenerators to
+receive sent and thrown values directly from the calling scope, and
+return a final value to the outer generator::
+
+ >>> def accumulate(start=0):
+ ... tally = start
+ ... while 1:
+ ... next = yield
+ ... if next is None:
+ ... return tally
+ ... tally += next
+ ...
+ >>> def gather_tallies(tallies, start=0):
+ ... while 1:
+ ... tally = yield from accumulate()
+ ... tallies.append(tally)
+ ...
+ >>> tallies = []
+ >>> acc = gather_tallies(tallies)
+ >>> next(acc) # Ensure the accumulator is ready to accept values
+ >>> for i in range(10):
+ ... acc.send(i)
+ ...
+ >>> acc.send(None) # Finish the first tally
+ >>> for i in range(5):
+ ... acc.send(i)
+ ...
+ >>> acc.send(None) # Finish the second tally
+ >>> tallies
+ [45, 10]
+
+The main principle driving this change is to allow even generators that are
+designed to be used with the ``send`` and ``throw`` methods to be split into
+multiple subgenerators as easily as a single large function can be split into
+multiple subfunctions.
+
(Implementation by Greg Ewing, integrated into 3.3 by Renaud Blanch, Ryan
Kelly and Nick Coghlan, documentation by Zbigniew Jędrzejewski-Szmek and
Nick Coghlan)