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を使う