『Java言語で学ぶデザインパターン入門第3版』をPythonで実装してみるシリーズ。
第1章の iterator パターン。なんでこれを第1部デザインパターンに慣れるの一発目に入れたのか謎。
from collections.abc import Iterable, Iterator
class Book:
def __init__(self, name: str) -> None:
self.name = name
class BookShelf(Iterable):
def __init__(self, maxsize: int) -> None:
self._books: list[Book] = [Book("")] * maxsize
self._last = 0
def get_book_at(self, index: int) -> Book:
return self._books[index]
def append_book(self, book: Book) -> None:
self._books[self._last] = book
self._last += 1
def get_length(self) -> int:
return self._last
def __iter__(self) -> Iterator[Book]:
return BookShelfIterator(self)
class BookShelfIterator(Iterator):
def __init__(self, book_shelf: BookShelf) -> None:
self._book_shelf = book_shelf
self._index = 0
def _has_next(self) -> bool:
if self._index < self._book_shelf.get_length():
return True
else:
return False
def __next__(self) -> Book:
if not self._has_next():
raise StopIteration()
book = self._book_shelf.get_book_at(self._index)
self._index += 1
return book
def main() -> None:
book_shelf = BookShelf(4)
book_shelf.append_book(Book("Around the World in 80 Days"))
book_shelf.append_book(Book("Bible"))
book_shelf.append_book(Book("Cinderella"))
book_shelf.append_book(Book("Daddy-Long-Legs"))
# 明示的にIteratorを使う方法
it = book_shelf.__iter__()
while True:
try:
book = next(it)
except StopIteration:
break
print(book.name)
print()
# for文を使う方法
for book in book_shelf:
print(book.name)
print()
if __name__ == "__main__":
main()
元 Java コードなのを無理やり Python 化してるので、読みにくいところもあるかもしれない。
コメント