Finally figured out member generators...

Bjorn Pettersen BPettersen at NAREX.com
Mon Mar 3 22:34:50 CET 2003


> From: Jeff Epler [mailto:jepler at unpythonic.net] 
> 
> Which version of Python are you using?
> 
> I just tried a similar example on Python 2.2.2 using "from __future__
> import generators", and there was no need to introduce a separate
> method, or call it in a strange way.
> 
> >>> from __future__ import generators
> >>> class R10:
> ...     def __iter__(self):   
> ...             for i in range(10): yield i
> ... 
> >>> list(R10())
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[...]

Thanks! I guess I got completely confused by the docs... According to
LibRef 2.2.5, __iter__() should return an _object_ that is "required to
support the iterator protocol". The iterator object protocol requires:

  __iter__(): which should return the iterator object itself
  next():     which should return the next object or raise StopIteration

I took that to mean that classes that wanted to be their own iterators
should "return self" in their __iter__() method [after all self
implements both __iter__ and next], and have next() produce successive
values on iterative calls until finally raising StopIteration. Like,
e.g.:

 >>> class D:
 ...   def __init__(self): self.v = 5
 ...   def __iter__(self): return self
 ...   def next(self):
 ...       for i in range(10):
 ...          yield i + self.v
 ...
 >>> d = D()
 >>> list(d)

which will recurse infitely. That __iter__ should return self.next(),
thus creating and returning an iterator object because of generator
semantics didn't occur to me since the whole point was to have the class
be it's own iterator... Oh, well, it was fun anyways :-)

-- bjorn





More information about the Python-list mailing list