いいえ。すべての呼び出しを大部分転送するアダプターを作成しますが、転送時に最後の行のコピーを保持しnext
、別のメソッドを呼び出してその行を再度ポップアウトさせます。
実際には、アダプターをファイルのラッパーではなく、反復可能なものをラップできるアダプターにします。これは、他のコンテキストで頻繁に役立つように聞こえるためです。
アダプターを使用するという Alex の提案itertools.tee
も機能しますが、一般的にこのケースを処理するために独自の反復子アダプターを作成する方がクリーンになると思います。
以下に例を示します。
class rewindable_iterator(object):
not_started = object()
def __init__(self, iterator):
self._iter = iter(iterator)
self._use_save = False
self._save = self.not_started
def __iter__(self):
return self
def next(self):
if self._use_save:
self._use_save = False
else:
self._save = self._iter.next()
return self._save
def backup(self):
if self._use_save:
raise RuntimeError("Tried to backup more than one step.")
elif self._save is self.not_started:
raise RuntimeError("Can't backup past the beginning.")
self._use_save = True
fiter = rewindable_iterator(file('file.txt', 'r'))
for line in fiter:
result = process_line(line)
if result is DoOver:
fiter.backup()
これを拡張して、複数の値でバックアップできるようにすることはそれほど難しくありません。