詳細な理解については、Python__iter__を参照してください-クラウド+コミュニティ-TencentCloud
例を見てみましょう:
class Fib:
def __init__(self, max):
self.max = max
def __iter__(self):
print('__iter__ called')
self.a = 0
self.b = 1
return self
def __next__(self):
print('__next__ called')
fib = self.a
if fib > self.max:
raise StopIteration
self.a, self.b = self.b, self.a + self.b
return fib
for i in Fib(3):
print(i)
# 输出
__iter__ called
__next__ called
0
__next__ called
1
__next__ called
1
__next__ called
2
__next__ called
このフィボナッチ数列ジェネレーターで__iter__を理解します。
__iter__を定義することは、このクラスがイテレーターであることを示します。反復の開始時に1回だけ実行されます。返されるのはオブジェクト自体です。オブジェクトに追加された2つの属性aとbもあります。次のステップは、raise StopIterationが発生するまで、ループ内で__next__を呼び出すことです。呼び出しプロセスは、フィボナッチ数列をシミュレートするプロセスです。
1 1 2 3 5 7 11 18...self.aの値がシーケンスの値であることがわかります。この値は、反復ごとにfib変数を介して出力する必要があります。self.a = 3の場合、それをfibに割り当て、fib> self.maxがfalseの場合、反復を終了します。秘訣は次のとおりです。シーケンスをそれ自体で反復させ、中間変数fibを使用して出力します。
イテレータでは、__ iter__と__next__が必要ですが、__init__は必須ではありません。
class Fib:
def __iter__(self):
print('__iter__ called')
self.a = 0
self.b = 1
self.max = 3
return self
def __next__(self):
print('__next__ called')
fib = self.a
if fib > self.max:
raise StopIteration
self.a, self.b = self.b, self.a + self.b
return fib
上記のコードの出力は、最初のコードと同じです。__iter__は1回しか許可されていないため、プロパティへの割り当てに使用できます。ただし、このようなFibクラスは、パラメーターを渡して構築することはできません。self.maxが組み込まれています。
理解を深めるために、別の例を見てみましょう。最初の項a1とステップサイズdが与えられた場合、最後の項がnに最も近い等差数列を返します。
# 等差数列公式 an = a1 + (n-1) * d
class Acu():
def __init__(self, a1, d, n):
self.a1 = a1
self.d = d
self.n = n
def __iter__(self):
return self
def __next__(self):
an = self.a1
if an > self.n:
raise StopIteration
else:
self.a1 += self.d
return an
for i in Acu(1, 2, 15):
print(i)
まったく同じ理由で、最初にiterを使用して、このオブジェクトがイテレーターであることを示し、次にnextを呼び出し、最初に最初の項目a1をanに割り当てて出力します。出力前に、a1は1ステップずつインクリメントされます。このように、anの値は変更されず、次にa1を介して値が割り当てられたときに変更されます。