イテレータパターンは、コレクションの要素にアクセスするための方法を提供するデザインパターンです。このパターンを使用することで、コレクションの内部表現を隠しながら、要素を順番に処理することができます。
イテレータパターンは、以下の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
ループを使ってイテレータを通じて本を出力します。このようにして、イテレータパターンを使用することで、コレクションの内部実装を隠しながら、要素にアクセスすることができるようになります。