質問
それを読んでいるにも関わらず、 __ iter __
がどのように機能するのか、まだよくわかりません。簡単な説明は何でしょうか?
def__iter __(self):return self
を見ました。これがどのように機能するのか、これがどのように機能するのかについての手順がわかりません。
解決
イテレータは、 __ iter __()
と __ next __()
(python2の next()
)の2つのメソッドを定義する必要があります。通常、オブジェクト自体は __ next __()
または next()
メソッドを定義するため、イテレーターとして自分自身を返すだけです。これにより、イテレータであるイテレータが作成されます。これらのメソッドは、 for
および in
ステートメントで使用されます。
-
Python 3のドキュメント: docs.python.org/ 3 / library / stdtypes.html#iterator-types
-
Python 2のドキュメント: docs.python.org/ 2 / library / stdtypes.html#iterator-types
他のヒント
簡単に言えば:
__ iter __
は、反復子(オブジェクトに含まれる次のアイテムを連続的に生成するオブジェクト)を返すクラスのメソッドを定義します。
__ iter __()
が返す反復子オブジェクトは、 next()
メソッドを定義している限り、ほとんどすべてのオブジェクトになります。
next
メソッドは、次のアイテムを生成するために for ... in ...
などのステートメントによって呼び出され、 next()
アイテムがなくなると、 StopIteration
例外が発生します。
これの素晴らしい点は、オブジェクトの反復方法を 定義できることです。また、 __ iter __
は、他のすべてのpython関数が操作方法を知っている共通のインターフェイスを提供します。
def __iter __(self):
の仕様は次のとおりです。反復子を返します。したがって、 self
がイテレータの場合、 return self
が明らかに適切です。
"イテレータであること" " __ next __(self)
メソッドを使用する" (Python 3では、Python 2では、問題のメソッドの名前は残念ながら単純な next
であり、明らかに特別なメソッドの名前設計の不具合です。)
Python 2.6以降では、イテレータを実装する最適な方法は、一般に collections
標準ライブラリ module -Python 2.6では、コードは次のようになります(代わりに __ next __
メソッドを呼び出すことを忘れないでください) Python 3):
import collections
class infinite23s(collections.Iterator):
def next(self): return 23
このクラスのインスタンスは、( itertools.repeat(23)
のように)繰り返し処理されると 23
の無限のコピーを返すため、ループを終了する必要があります。ポイントは、サブクラス化 collections.Iterator
があなたに代わって正しい __ iter __
メソッドを追加することです-ここでは大したことではなく、良い一般原則です(繰り返しのような定型的なコードは避けてください)イテレータの標準的な1行の __ iter __
-繰り返しでは、付加価値はなく、多くの減算価値があります!-)。
__ iter__メソッドをサポートするクラスは、イテレータオブジェクトインスタンス、 next()メソッドをサポートするオブジェクトを返します。このオブジェクトは、「for」文で使用できます。 and" in"。
Pythonでは、イテレータはイテレータプロトコルをサポートするオブジェクトです。そのプロトコルの一部は、オブジェクトがイテレータオブジェクトを返す __ iter __()
メソッドを持たなければならないことです。これにより、オブジェクトがイテレーターの責任を内部クラスに渡したり、特別なオブジェクトを作成したりできる柔軟性が得られると思います。いずれにせよ、 __ iter __()
メソッドには通常1行しかなく、多くの場合、その行は単に return self
プロトコルの他の部分は next()
メソッドで、これが実際の作業を行う場所です。このメソッドは、次のものを把握または作成または取得し、それを返す必要があります。それがどこにあるかを追跡する必要があるかもしれませんので、次に呼び出されたとき、それは本当に次のものを返します。
シーケンスの次のものを返すオブジェクトを取得したら、次のようなforループを折りたたみます:
myname = "Fredericus"
x = []
for i in [1,2,3,4,5,6,7,8,9,10]:
x.append(myname[i-1])
i = i + 1 # get the next i
print x
これに:
myname = "Fredericus"
x = [myname[i] for i in range(10)]
print x
range(10)はイテレータプロトコルに従うオブジェクトであり、リスト内包はイテレータプロトコルを使用する構造であるため、次のiの値を取得するコードがどこにもないことに注意してください。
イテレータプロトコルを直接使用することもできます。たとえば、CSVファイルを処理するスクリプトを作成するとき、私はこれをよく書きます:
mydata = csv.reader(open('stuff.csv')
mydata.next()
for row in mydata:
# do something with the row.
next()
を呼び出してヘッダー行をスキップし、 for <の組み込みの
in
演算子を介して間接的に使用して、イテレータを直接使用しています/ code>ステートメント。