[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