|
Data Structures and Algorithms
with Object-Oriented Design Patterns in Python |
In this section we introduce an abstraction called an iterator . An iterator provides the means to access one-by-one all the objects in a container.
A Python iterator is any class that provides two methods called __iter__ and next and that implements the iterator protocol which we describe below. In order to use an iterator to access the objects in a container, that container must provide iteration support. Specifically, that class must implement a method called __iter__ that returns the corresponding iterator for that class.
The idea is that for every concrete container class
derived from the Container base class
we will also implement a related class
derived from the abstract Iterator class shown in Program
The Iterator class comprises three methods, __init__, __iter__, and next. The __init__ and __iter__ methods are straightforward. The abstract next method provided in a derived class is required to implement the iterator protocol.
In order to understand the iterator protocol, it is best to consider first an example which illustrates the use of an iterator. Consider a concrete container class, say SomeContainer, that implements the Container interface. The following code fragment illustrates the use of an iterator to access one-by-one the objects contained in the container:
c = SomeContainer()
# ...
i = iter(c) # Equivalent to c.__iter__()
while True:
try:
obj = i.next()
print obj
except StopIteration:
break
In order to have the desired effect, the next method must behave as follows:
A certain amount of care is required when defining and using iterators. In order to simplify the implementation of iterators, we shall assume that while an iterator is in use, the associated container will not be modified.