イテレータパターンは、コレクションの要素にアクセスするための方法を提供するデザインパターンです。このパターンを使用することで、コレクションの内部表現を隠しながら、要素を順番に処理することができます。
イテレータパターンは、以下の2つの主要なコンポーネントで構成されます。
next()メソッドで次の要素を取得し、has_next()メソッドで要素が残っているかを確認します。以下の例では、Bookというクラスを使って本のコレクションを作成し、そのコレクションをイテレータで走査します。
まずは、Bookクラスを定義します。
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return f"'{self.title}' by {self.author}"
このクラスは、本のタイトルと著者を保持します。
次に、複数の本を保持するBookCollectionクラスを定義します。このクラスにはイテレータを生成するメソッドも含まれます。
class BookCollection:
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
def __iter__(self):
return BookIterator(self)
__iter__メソッドは、BookIteratorを返します。
次に、実際にイテレータの機能を持つBookIteratorクラスを定義します。
class BookIterator:
def __init__(self, collection):
self._collection = collection
self._index = 0
def __iter__(self):
return self
def __next__(self):
if self._index < len(self._collection.books):
book = self._collection.books[self._index]
self._index += 1
return book
else:
raise StopIteration
このクラスでは、__next__メソッドが次の本を返し、すべての本が返された後はStopIteration例外を発生させます。
最後に、これらのクラスを使って本のコレクションを作成し、イテレータで遍歴します。
if __name__ == "__main__":
collection = BookCollection()
collection.add_book(Book("1984", "George Orwell"))
collection.add_book(Book("To Kill a Mockingbird", "Harper Lee"))
collection.add_book(Book("The Great Gatsby", "F. Scott Fitzgerald"))
for book in collection:
print(book)
__iter__メソッドを通じてイテレータを提供します。ここでは、add_bookメソッドで本を追加します。__next__メソッドが重要で、ここで要素を返し、要素がなくなった場合にはStopIterationを投げます。BookCollectionをインスタンス化し、本を追加し、forループを使ってイテレータを通じて本を出力します。このようにして、イテレータパターンを使用することで、コレクションの内部実装を隠しながら、要素にアクセスすることができるようになります。