How to stop iteration with __iter__() ?

Steven D'Aprano steve at
Wed Aug 20 15:43:49 CEST 2008

On Wed, 20 Aug 2008 06:16:17 -0700, MRAB wrote:

> So it's defined behaviour that an exhausted iterable will always raise
> StopIteration no matter how many times it's asked for the next value?

Be careful -- an iterable is not the same as an iterator.

Iterables are anything that you can iterate over. This includes strings, 
lists, tuples, dicts and, yes, iterators.

But not all iterables are iterators. Only iterators raise StopIteration. 
The defined behaviour of iterators is that once exhausted, they will 
always raise StopIteration.

Basically, Python will do the right thing in a for loop regardless of 
whether you pass an iterator or some other type of iterable. You don't 
have to worry about the mechanics of it, but if you care, it works 
something like this:

When Python executes a for-loop:

for item in obj:

it does something kind of like this:

if hasattr(obj, "next"):
    # Looks like an iterator.
    while True:
            item =
        except StopIteration:
        execute BLOCK
elif hasattr(obj, "__getitem__"):
    # Looks like a string, or list, or similar.
    i = 0
    while True:
            item = obj[i]
        except IndexError:
        execute BLOCK
        i += 1
    raise TypeError('object not iterable')


More information about the Python-list mailing list