[Python-checkins] python/dist/src/Doc/tut tut.tex,1.193,1.194
rhettinger@users.sourceforge.net
rhettinger@users.sourceforge.net
Fri, 11 Jul 2003 11:58:13 -0700
Update of /cvsroot/python/python/dist/src/Doc/tut
In directory sc8-pr-cvs1:/tmp/cvs-serv2295
Modified Files:
tut.tex
Log Message:
Minor fixups and added sections for iterators and generators.
Index: tut.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v
retrieving revision 1.193
retrieving revision 1.194
diff -C2 -d -r1.193 -r1.194
*** tut.tex 7 Jul 2003 21:00:29 -0000 1.193
--- tut.tex 11 Jul 2003 18:58:11 -0000 1.194
***************
*** 3732,3736 ****
of \code{MyClass.i} by assignment. \member{__doc__} is also a valid
attribute, returning the docstring belonging to the class: \code{"A
! simple example class"}).
Class \emph{instantiation} uses function notation. Just pretend that
--- 3732,3736 ----
of \code{MyClass.i} by assignment. \member{__doc__} is also a valid
attribute, returning the docstring belonging to the class: \code{"A
! simple example class"}.
Class \emph{instantiation} uses function notation. Just pretend that
***************
*** 4129,4133 ****
function object corresponding to the method.
! \subsection{Exceptions Are Classes Too\label{exceptionClasses}}
User-defined exceptions are identified by classes as well. Using this
--- 4129,4134 ----
function object corresponding to the method.
!
! \section{Exceptions Are Classes Too\label{exceptionClasses}}
User-defined exceptions are identified by classes as well. Using this
***************
*** 4185,4188 ****
--- 4186,4302 ----
+ \section{Iterators\label{iterators}}
+
+ By now, you've probably noticed that most container objects can looped over
+ using a \code{for} statement:
+
+ \begin{verbatim}
+ for element in [1, 2, 3]:
+ print element
+ for element in (1, 2, 3):
+ print element
+ for key in {'one':1, 'two':2}:
+ print key
+ for char in "123":
+ print char
+ for line in open("myfile.txt"):
+ print line
+ \end{verbatim}
+
+ This style of access is clear, concise, and convenient. The use of iterators
+ pervades and unifies Python. Behind the scenes, the \code{for} statement calls
+ \function{iter()} on the container object. The function returns an iterator
+ object that defines the method \method{next()} which accesses elements in the
+ container one at a time. When there are no more elements, \method{next()}
+ raises a \exception{StopIteration} exception which tells the \code{for} loop
+ to terminate. This example shows how it all works:
+
+ \begin{verbatim}
+ >>> s = 'abc'
+ >>> it = iter(s)
+ >>> it
+ <iterator object at 0x00A1DB50>
+ >>> it.next()
+ 'a'
+ >>> it.next()
+ 'b'
+ >>> it.next()
+ 'c'
+ >>> it.next()
+
+ Traceback (most recent call last):
+ File "<pyshell#6>", line 1, in -toplevel-
+ it.next()
+ StopIteration
+ \end{verbatim}
+
+ Having seen the mechanics behind the iterator protocol, it is easy to add
+ iterator behavior to your classes. Define a \method{__iter__()} method
+ which returns an object with a \method{next()} method. If the class defines
+ \method{next()}, then \method{__iter__()} can just return \code{self}:
+
+ \begin{verbatim}
+ >>> class Reverse:
+ "Iterator for looping over a sequence backwards"
+ def __init__(self, data):
+ self.data = data
+ self.index = len(data)
+ def __iter__(self):
+ return self
+ def next(self):
+ if self.index == 0:
+ raise StopIteration
+ self.index = self.index - 1
+ return self.data[self.index]
+
+ >>> for char in Reverse('spam'):
+ print char
+
+ m
+ a
+ p
+ s
+ \end{verbatim}
+
+
+ \section{Generators\label{generators}}
+
+ Generators are a simple and powerful tool for creating iterators. They are
+ written like regular functions but use the \keyword{yield} statement whenever
+ they want to return data. Each time the \method{next()} is called, the
+ generator resumes where it left-off (it remembers all the data values and
+ which statement was last executed). An example shows that generators can
+ be trivially easy to create:
+
+ \begin{verbatim}
+ >>> def reverse(data):
+ for index in range(len(data)-1, -1, -1):
+ yield data[index]
+
+ >>> for char in reverse('golf'):
+ print char
+
+ f
+ l
+ o
+ g
+ \end{verbatim}
+
+ Anything that can be done with generators can also be done with class based
+ iterators as described in the previous section. What makes generators so
+ compact is that the \method{__iter__()} and \method{next()} methods are
+ created automatically.
+
+ Another other key feature is that the local variables and execution state
+ are automatically saved between calls. This made the function easier to write
+ and much more clear than an approach using class variables like
+ \code{self.index} and \code{self.data}.
+
+ In addition to automatic method creation and saving program state, when
+ generators terminate, they automatically raise \exception{StopIteration}.
+ In combination, these features make it easy to create iterators with no
+ more effort than writing a regular function.
+
+
\chapter{What Now? \label{whatNow}}
***************
*** 4361,4365 ****
#
# Store the file in ~/.pystartup, and set an environment variable to point
! # to it, e.g. "export PYTHONSTARTUP=/max/home/itamar/.pystartup" in bash.
#
# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the
--- 4475,4479 ----
#
# Store the file in ~/.pystartup, and set an environment variable to point
! # to it: "export PYTHONSTARTUP=/max/home/itamar/.pystartup" in bash.
#
# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the