Нет. Я бы сделал адаптер, который в основном перенаправлял бы все вызовы, но сохранял копию последней строки, когда вы сделали next
, а затем позволял бы вам вызывать другой метод, чтобы эта строка снова всплывала.
Я бы на самом деле сделал адаптер адаптером, который мог бы обернуть любую итерацию вместо оболочки для файла, потому что это звучит так, как будто это часто будет полезно в других контекстах.
Предложение Алекса об использовании 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()
Это не будет слишком сложно расширить на что-то, что позволит вам делать резервные копии более чем на одно значение.