|
32 | 32 | a particular new feature. |
33 | 33 |
|
34 | 34 |
|
| 35 | +%====================================================================== |
| 36 | +\section{PEP 255: Simple Generators} |
| 37 | + |
| 38 | +In Python 2.2, generators were added as an optional feature, to be |
| 39 | +enabled by a \code{from __future__ import generators} directive. In |
| 40 | +2.3 generators no longer need to be specially enabled, and are now |
| 41 | +always present; this means that \keyword{yield} is now always a |
| 42 | +keyword. The rest of this section is a copy of the description of |
| 43 | +generators from the ``What's New in Python 2.2'' document; if you read |
| 44 | +it when 2.2 came out, you can skip the rest of this section. |
| 45 | + |
| 46 | +Generators are a new feature that interacts with the iterators |
| 47 | +introduced in Python 2.2. |
| 48 | + |
| 49 | +You're doubtless familiar with how function calls work in Python or |
| 50 | +C. When you call a function, it gets a private namespace where its local |
| 51 | +variables are created. When the function reaches a \keyword{return} |
| 52 | +statement, the local variables are destroyed and the resulting value |
| 53 | +is returned to the caller. A later call to the same function will get |
| 54 | +a fresh new set of local variables. But, what if the local variables |
| 55 | +weren't thrown away on exiting a function? What if you could later |
| 56 | +resume the function where it left off? This is what generators |
| 57 | +provide; they can be thought of as resumable functions. |
| 58 | + |
| 59 | +Here's the simplest example of a generator function: |
| 60 | + |
| 61 | +\begin{verbatim} |
| 62 | +def generate_ints(N): |
| 63 | + for i in range(N): |
| 64 | + yield i |
| 65 | +\end{verbatim} |
| 66 | + |
| 67 | +A new keyword, \keyword{yield}, was introduced for generators. Any |
| 68 | +function containing a \keyword{yield} statement is a generator |
| 69 | +function; this is detected by Python's bytecode compiler which |
| 70 | +compiles the function specially as a result. |
| 71 | + |
| 72 | +When you call a generator function, it doesn't return a single value; |
| 73 | +instead it returns a generator object that supports the iterator |
| 74 | +protocol. On executing the \keyword{yield} statement, the generator |
| 75 | +outputs the value of \code{i}, similar to a \keyword{return} |
| 76 | +statement. The big difference between \keyword{yield} and a |
| 77 | +\keyword{return} statement is that on reaching a \keyword{yield} the |
| 78 | +generator's state of execution is suspended and local variables are |
| 79 | +preserved. On the next call to the generator's \code{.next()} method, |
| 80 | +the function will resume executing immediately after the |
| 81 | +\keyword{yield} statement. (For complicated reasons, the |
| 82 | +\keyword{yield} statement isn't allowed inside the \keyword{try} block |
| 83 | +of a \code{try...finally} statement; read \pep{255} for a full |
| 84 | +explanation of the interaction between \keyword{yield} and |
| 85 | +exceptions.) |
| 86 | + |
| 87 | +Here's a sample usage of the \function{generate_ints} generator: |
| 88 | + |
| 89 | +\begin{verbatim} |
| 90 | +>>> gen = generate_ints(3) |
| 91 | +>>> gen |
| 92 | +<generator object at 0x8117f90> |
| 93 | +>>> gen.next() |
| 94 | +0 |
| 95 | +>>> gen.next() |
| 96 | +1 |
| 97 | +>>> gen.next() |
| 98 | +2 |
| 99 | +>>> gen.next() |
| 100 | +Traceback (most recent call last): |
| 101 | + File "<stdin>", line 1, in ? |
| 102 | + File "<stdin>", line 2, in generate_ints |
| 103 | +StopIteration |
| 104 | +\end{verbatim} |
| 105 | + |
| 106 | +You could equally write \code{for i in generate_ints(5)}, or |
| 107 | +\code{a,b,c = generate_ints(3)}. |
| 108 | + |
| 109 | +Inside a generator function, the \keyword{return} statement can only |
| 110 | +be used without a value, and signals the end of the procession of |
| 111 | +values; afterwards the generator cannot return any further values. |
| 112 | +\keyword{return} with a value, such as \code{return 5}, is a syntax |
| 113 | +error inside a generator function. The end of the generator's results |
| 114 | +can also be indicated by raising \exception{StopIteration} manually, |
| 115 | +or by just letting the flow of execution fall off the bottom of the |
| 116 | +function. |
| 117 | + |
| 118 | +You could achieve the effect of generators manually by writing your |
| 119 | +own class and storing all the local variables of the generator as |
| 120 | +instance variables. For example, returning a list of integers could |
| 121 | +be done by setting \code{self.count} to 0, and having the |
| 122 | +\method{next()} method increment \code{self.count} and return it. |
| 123 | +However, for a moderately complicated generator, writing a |
| 124 | +corresponding class would be much messier. |
| 125 | +\file{Lib/test/test_generators.py} contains a number of more |
| 126 | +interesting examples. The simplest one implements an in-order |
| 127 | +traversal of a tree using generators recursively. |
| 128 | + |
| 129 | +\begin{verbatim} |
| 130 | +# A recursive generator that generates Tree leaves in in-order. |
| 131 | +def inorder(t): |
| 132 | + if t: |
| 133 | + for x in inorder(t.left): |
| 134 | + yield x |
| 135 | + yield t.label |
| 136 | + for x in inorder(t.right): |
| 137 | + yield x |
| 138 | +\end{verbatim} |
| 139 | + |
| 140 | +Two other examples in \file{Lib/test/test_generators.py} produce |
| 141 | +solutions for the N-Queens problem (placing $N$ queens on an $NxN$ |
| 142 | +chess board so that no queen threatens another) and the Knight's Tour |
| 143 | +(a route that takes a knight to every square of an $NxN$ chessboard |
| 144 | +without visiting any square twice). |
| 145 | + |
| 146 | +The idea of generators comes from other programming languages, |
| 147 | +especially Icon (\url{http://www.cs.arizona.edu/icon/}), where the |
| 148 | +idea of generators is central. In Icon, every |
| 149 | +expression and function call behaves like a generator. One example |
| 150 | +from ``An Overview of the Icon Programming Language'' at |
| 151 | +\url{http://www.cs.arizona.edu/icon/docs/ipd266.htm} gives an idea of |
| 152 | +what this looks like: |
| 153 | + |
| 154 | +\begin{verbatim} |
| 155 | +sentence := "Store it in the neighboring harbor" |
| 156 | +if (i := find("or", sentence)) > 5 then write(i) |
| 157 | +\end{verbatim} |
| 158 | + |
| 159 | +In Icon the \function{find()} function returns the indexes at which the |
| 160 | +substring ``or'' is found: 3, 23, 33. In the \keyword{if} statement, |
| 161 | +\code{i} is first assigned a value of 3, but 3 is less than 5, so the |
| 162 | +comparison fails, and Icon retries it with the second value of 23. 23 |
| 163 | +is greater than 5, so the comparison now succeeds, and the code prints |
| 164 | +the value 23 to the screen. |
| 165 | + |
| 166 | +Python doesn't go nearly as far as Icon in adopting generators as a |
| 167 | +central concept. Generators are considered a new part of the core |
| 168 | +Python language, but learning or using them isn't compulsory; if they |
| 169 | +don't solve any problems that you have, feel free to ignore them. |
| 170 | +One novel feature of Python's interface as compared to |
| 171 | +Icon's is that a generator's state is represented as a concrete object |
| 172 | +(the iterator) that can be passed around to other functions or stored |
| 173 | +in a data structure. |
| 174 | + |
| 175 | +\begin{seealso} |
| 176 | + |
| 177 | +\seepep{255}{Simple Generators}{Written by Neil Schemenauer, Tim |
| 178 | +Peters, Magnus Lie Hetland. Implemented mostly by Neil Schemenauer |
| 179 | +and Tim Peters, with other fixes from the Python Labs crew.} |
| 180 | + |
| 181 | +\end{seealso} |
| 182 | + |
| 183 | + |
35 | 184 | %====================================================================== |
36 | 185 | \section{New and Improved Modules} |
37 | 186 |
|
@@ -80,9 +229,12 @@ \section{Other Changes and Fixes} |
80 | 229 | % ====================================================================== |
81 | 230 | \section{C Interface Changes} |
82 | 231 |
|
| 232 | +Patch \#527027: Allow building python as shared library with |
| 233 | +--enable-shared |
| 234 | + |
83 | 235 | pymalloc is now enabled by default (also mention debug-mode pymalloc) |
84 | 236 |
|
85 | | -Memory API reworking |
| 237 | +Memory API reworking -- which functions are deprecated? |
86 | 238 |
|
87 | 239 | PyObject_DelItemString() added |
88 | 240 |
|
|
0 commit comments