
Python Cookbook [Delegating Iteration : 独自クラスへのイテレーション機能の実装] 投稿一覧へ戻る
Published 2020年5月1日19:41 by T.Tsuyoshi
Problem:
list や tuple といったイテラブルを属性値として含む独自のコンテナクラスがある場合に、そのクラス自体でイテレーション機能を提供したい。
Solution:
クラス内で __iter__() メソッドを定義し、実態として、内部で保持するコンテナのイテレーターに動作をお任せするだけです、楽チンです。
class Topping:
def __init__(self, value):
self._value = value
self._pizza = []
def __repr__(self):
return 'Topping [{!r}]'.format(self._value)
def add_topping(self, topping):
self._pizza.append(topping)
def __iter__(self):
return iter(self._pizza)
if __name__ == '__main__':
base = Topping('dough')
topping1 = Topping('cheese')
topping2 = Topping('shrimp')
topping3 = Topping('green pepper')
topping4 = Topping(4)
base.add_topping(topping1)
base.add_topping(topping2)
base.add_topping(topping3)
base.add_topping(topping4)
for tp in base:
print(tp)
def __init__(self, value):
self._value = value
self._pizza = []
def __repr__(self):
return 'Topping [{!r}]'.format(self._value)
def add_topping(self, topping):
self._pizza.append(topping)
def __iter__(self):
return iter(self._pizza)
if __name__ == '__main__':
base = Topping('dough')
topping1 = Topping('cheese')
topping2 = Topping('shrimp')
topping3 = Topping('green pepper')
topping4 = Topping(4)
base.add_topping(topping1)
base.add_topping(topping2)
base.add_topping(topping3)
base.add_topping(topping4)
for tp in base:
print(tp)
# Topping ['cheese']
# Topping ['shrimp']
# Topping ['green pepper']
# Topping [4]
Python におけるイテレータープロトコルでは、実際のイテレーション作業を受け持つ __next__() メソッドを実装したイテレーターオブジェクトを返す __iter__() メソッドの実装が求められます。
今回の例のように、内部で保持するコンテナオブジェクトの要素をイテレートするだけなのであれば、何も考える必要はありません。
そのコンテナオブジェクトのイテレーターに全てお任せです。
このコードで利用している iter(s) メソッドは、s.__iter__() を呼び出して対象オブジェクトのイテレーターを返しているだけです。
こちらの投稿にも興味があるかもしれません...
- 【Python 雑談・雑学 + coding challenge】iterator protocol の実装 --- __iter__ 特殊関数は何を返すべき? イテレータオブジェクト ( iterator object ) なら何でも、そう、generator expression でもOKです!
- Python Cookbook [Implementing the Iterator Protocol : イテレータープロトコルの実装]
- 【 Effective Python, 2nd Edition 】throw() メソッドを利用したジェネレータ ( generator ) 内部での状態遷移はなるだけ避けましょう。ネストが深くなってコードの読解性が落ちちゃいますよ!
- 【 Effective Python, 2nd Edition 】引数として受け取った値を関数内で複数回「消費」する場合には要注意! イテレータ ( iterator ) とコンテナ ( container ) の違いをちゃんと認識しよう!
0 comments
コメントはまだありません。
コメントを追加する(不適切と思われるコメントは削除する場合があります)