PyJUGの石本 敦夫さんのスライドをみた。PythonはなんでもかんでもIteratorにすることが可能。
スライドより、Iteratorを実装したオブジェクト作成例
class AIterator(object): """seq1,se2内の要素を交互に返すIterator""" def __init__( self, seq1,seq2 ): self._seqs = ( seq1, seq2 ) self._cur = 0 self._max = min( len(seq1), len(seq2) )#最大インデックス値 def __iter__(self): return self def next(self): n,idx = self._cur %2 , self._cur //2 if idx >= self._max: raise StopIteration #Iterate終了 ret = self._seqs[n][idx] self._cur += 1 return ret for v in AIterator( range(10), range(100, 110) ): print v
注目するのは以下の三点
- next()
- raise StopIteration
- __iter__()
これがIteratorの重要点。
for x in A: でLoopさせたいときは、次の関数を作っておく。
def next(self) #繰り返しさせるオブジェクト(raise StopIterationする関数) def __iter__(self) #繰り返しさせるオブジェクトを返すメソッド(nextをもったオブジェクト)
の二つのメソッドがあればいい。
一般的には
- Iteratable Object#繰り返し可能オブジェクト
- Iterator Object#繰り返しオブジェクト
と呼ぶらしい。
実装例。File オブジェクトを見てみる
inFile = open("./foo.txt") for line in inFile: print line
__builtin__のリファレンスより
open(name[, mode[, buffering]]) -> file object
Open a file using the file() type, returns a file object.
fileのリファレンスより、__iter__とnextがある。
next :
x.next() -> the next value, or raise StopIteration
__iter__:
x.__iter__() <==> iter(x)
open の返す、file オブジェクトがiteratorable なオブジェクトでIteratorを返してくれる。
__iter__の返すオブジェクトがnextを持っていればいい。nextはStopIteration Exceptionをthrowする
これはSimpleで良いよね。
JavaのObject指向に近い言語だと、Interfaceを使う。Pythonには無いので、マニュアルに「これらの関数を作ってね」と書いてあるわけだ。Interfaceが無いと、チーム開発時に説明しにくいよね。
JavaのObject指向を取り入れた(と思う)PHP5でもInterfaceを使う