どうすれば作成できますか?反復子Python では?
たとえば、インスタンスに論理的にいくつかの値が「含まれる」クラスがあるとします。
class Example:
def __init__(self, values):
self.values = values
次のようなコードを書けるようになりたいです:
e = Example([1, 2, 3])
# Each time through the loop, expose one of the values from e.values
for value in e:
print("The example object contains", value)
より一般的には、イテレータは値の取得元を制御したり、インスタンスの特定の属性を考慮するのではなく、その場で値を計算したりできる必要があります。
ベストアンサー1
Python のイテレータ オブジェクトはイテレータ プロトコルに準拠しており、基本的には と の 2 つのメソッドを提供し__iter__()
ます__next__()
。
__iter__
反復子オブジェクトを返し、ループの開始時に暗黙的に呼び出されます。この
__next__()
メソッドは次の値を返し、ループの増分ごとに暗黙的に呼び出されます。このメソッドは、返す値がなくなったときに StopIteration 例外を発生させます。これは、反復処理を停止するためにループ構造によって暗黙的にキャプチャされます。
カウンターの簡単な例を次に示します。
class Counter:
def __init__(self, low, high):
self.current = low - 1
self.high = high
def __iter__(self):
return self
def __next__(self): # Python 2: def next(self)
self.current += 1
if self.current < self.high:
return self.current
raise StopIteration
for c in Counter(3, 9):
print(c)
次のように印刷されます:
3
4
5
6
7
8
前回の回答で説明したように、ジェネレータを使用して記述する方が簡単です。
def counter(low, high):
current = low
while current < high:
yield current
current += 1
for c in counter(3, 9):
print(c)
印刷される出力は同じになります。内部的には、ジェネレーター オブジェクトはイテレータ プロトコルをサポートし、Counter クラスとほぼ同様の処理を実行します。
デイヴィッド・メルツの記事、イテレータとシンプルなジェネレータ、これはかなり良い紹介です。