[Tutor] Here is newbie doc on how to implement generators

Kent Johnson kent37 at tds.net
Tue Jul 17 00:13:35 CEST 2007


Dave Kuhlman wrote:
> I find iterators and generators fascinating.  So, in order to try
> to understand them better myself, I've written up some notes.  I'm
> hoping that these notes might help someone new to the generators
> and iterators in Python.  You can find it here:
> 
>     http://www.rexx.com/~dkuhlman/python_comments.html
>     http://www.rexx.com/~dkuhlman/python_comments.html#iterators-and-generators
> 
> I'll appreciate any comments and suggestions that might help me
> improve it.

In the Consumers section, the first time you mention the iterator 
protocol, you omit mention of __init__() - this is a required method of 
an iterator.

In the section "The iterator protocol", the __iter__() bullet, "(2) 
return the value returned by a generator method" is not correct. An 
iterator must return self from __iter__(). An object that returns a 
(new) generator from __iter__() is an iterable, not an iterator.

In some cases there is no need to write a separate generator method and 
call it in __iter__(); __iter__() itself can be written as a generator 
method using yield. This works if the generator method doesn't need any 
arguments.

Your Doubler class will not behave correctly because of the 
re-initialization of the index in __iter__(). Calling __iter__() should 
not have any side effects. Here is an example of why this is a problem, 
using Doubler as you have written it:

In [9]: d=Doubler(range(5))
In [10]: d.next()
Out[10]: 0
In [11]: d.next()
Out[11]: 2
In [12]: for i in d: print i
    ....:
0
2
4
6
8

Notice how the for loop resets the iterator (because it calls __iter__() 
to make sure it has an iterator). Compare with a correctly implemented 
iterator:

In [13]: it = iter(range(5))
In [14]: it.next()
Out[14]: 0
In [15]: it.next()
Out[15]: 1
In [16]: for i in it: print i
    ....:
2
3
4

Double would actually be easier to implement with __iter__() as a 
generator method.

I already commented on the pitfalls of making an object its own 
iterator. In the standard library, a file is its own iterator. That 
makes sense because it is a wrapper around a singleton state - the seek 
position of the file. I don't think it makes much sense in general to 
have an object be its own iterator unless the object is just an iterator.

Another reference is the What's New doc for Python 2.2:
http://www.python.org/doc/2.2.3/whatsnew/node4.html
and the following page.

Kent


More information about the Tutor mailing list