クラスで __getitem__ を定義すると反復可能になるのはなぜですか?
たとえば、私が書いた場合:
class b:
def __getitem__(self, k):
return k
cb = b()
for k in cb:
print k
出力が得られます:
0
1
2
3
4
5
6
7
8
...
「for k in cb:」からエラーが返されることを期待しています。
クラスで __getitem__ を定義すると反復可能になるのはなぜですか?
たとえば、私が書いた場合:
class b:
def __getitem__(self, k):
return k
cb = b()
for k in cb:
print k
出力が得られます:
0
1
2
3
4
5
6
7
8
...
「for k in cb:」からエラーが返されることを期待しています。
反復のサポートは__getitem__
、PEP234 が主要な概念として反復可能性を導入したときに、よりスムーズな移行を可能にする「レガシー機能」と見なすことができます。これは、整数 0、1、&c__iter__
を受け入れないクラスにのみ適用され、インデックスが高くなりすぎると発生します (発生した場合)。通常、以前にコーディングされた「シーケンス」クラスが表示されます (ただし、この方法で新しいクラスをコーディングすることを妨げるものは何もありません)。__getitem__
IndexError
__iter__
個人的には、新しいコードではこれに依存したくありませんが、廃止されたり、なくなったりするわけではありません (Python 3 でも問題なく動作します)。反復可能性を暗黙的にサポートすることに頼るのではなく、反復可能性を明示的にサポートしたい__getitem__
のですが、大したことではありません)。
イテレータを定義するPEP234を見ると、次のように書かれています。
1. An object can be iterated over with "for" if it implements
__iter__() or __getitem__().
2. An object can function as an iterator if it implements next().
__getitem__
反復子プロトコルよりも前から存在し、過去には反復可能にする唯一の方法でした。そのため、繰り返しの方法として引き続きサポートされています。基本的に、反復のプロトコルは次のとおりです。
メソッドを確認し__iter__
ます。存在する場合は、新しい反復プロトコルを使用します。
__getitem__
それ以外の場合は、 IndexError が発生するまで、連続して大きな整数値で呼び出してみてください。
(2) はこれを行う唯一の方法でしたが、反復をサポートするために必要以上のことを想定しているという欠点がありました。反復をサポートするには、ランダム アクセスをサポートする必要がありました。ランダム アクセスをサポートする必要がありました。これは、ファイルやネットワーク ストリームなど、前に進むのは簡単でしたが、後ろに進むにはすべてを保存する必要があるため、はるかに高価でした。 __iter__
ランダムアクセスなしで反復を許可しましたが、ランダムアクセスは通常、とにかく反復を許可し、下位互換性を壊すと悪いため、__getitem__
引き続きサポートされます。
__getitem__
反復を含む特別な動作をオブジェクトに追加 するなどの特別なメソッド。
http://docs.python.org/reference/datamodel.html#object. ゲットアイテム
「 for ループは、シーケンスの終わりを適切に検出できるように、不正なインデックスに対して IndexError が発生することを期待しています。」
シーケンスの終わりを知らせるために IndexError を発生させます。
あなたのコードは基本的に次のものと同等です:
i = 0
while True:
try:
yield object[i]
i += 1
except IndexError:
break
object は for ループで繰り返し処理するものです。
これは歴史的な理由によるものです。Python 2.2 より前は、__getitem__ が for ループで反復できるクラスを作成する唯一の方法でした。2.2 では __iter__ プロトコルが追加されましたが、下位互換性を維持するために __getitem__ は for ループで引き続き機能します。
cb[0]
と同じだからですcb.__getitem__(0)
。これについては、 Python のドキュメントを参照してください。