More baby squeaking - iterators in a class
Terry Reedy
tjreedy at udel.edu
Fri Dec 31 21:44:54 EST 2004
"M.E.Farmer" <mefjr75 at hotmail.com> wrote in message
news:1104511354.639920.246830 at c13g2000cwb.googlegroups.com...
> Terry Reedy wrote:
>>will. Try ip=iter(p) followed by ip.next and ip.next() instead.
> Does that mean if you dont't call iter(() on your instance or have a
> next() method you can't do this:
>>>>> p=R3('eggs')
>>>>> for i in p:
>>>>> print i
Ignoring the older iteration method based on __getitem__, which I recommend
you do ignore, yes, you cannot do that.
> I am asking because I want to fully understand what makes an
> *iterator*.
An iterator is an object with an __iter__ method that returns 'self' and a
parameterless .next() method that on each call either returns an object or
raises StopIteration.
An iterable is an object with an __iter__ method that returns an iterator.
A generator function (one containing yield in the code body), when called,
returns a generator, which is a particular type of iterator. So, a class
with .__iter__ written as a generator function has iterable instances.
I can think of three reasons to go this latter route:
1. Writing a generator function may be easier that writing a standard
function for .next.
2. The resulting iteration may be faster.
3. Iterating with a separate generator allows iteration without disturbing
the data of the instance (ie, non destructively). This means that one can
iterate more than once, even more than once at the same time. Consider
'multiplying' a sequence by itself:
(i,j) for i in iterable for j in iterable
iter(iterable) is called once and then once again for each item yielded by
the first call.
Terry J. Reedy
More information about the Python-list
mailing list