关于python:使用f.next()迭代时返回多行

rewinding multiple lines when iterating with f.next()

这个问题的后续行动。如何修改此代码以允许重绕多行?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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


这就是我提出的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from collections import deque
class rewindable_iterator(object):
    not_started = object()

    def __init__(self, filename,deque_max_length=2):
        self._f=open(filename,'r')
        self._iter = iter(self._f)
        self._use_save = False
#        self._use_save2 = False
        self._save = self.not_started
        self._use_num=0
        self._deque=deque([],deque_max_length)

    def __iter__(self):
        return self
    def __enter__(self):
        return self
    def readline(self):
        return self._iter.readline()

    def __exit__(self,exc_type, exc_value, traceback):
        if exc_type is not None:
            print exc_type, exc_value, traceback
        self._f.close()

    def next(self):
        if self._use_save:
            self._use_num -= 1
            if not self._use_num:
                self._use_save = False
            return self._deque[-self._use_num-1]
        else:
            self._save = self._iter.next()
            self._deque.append(self._save)
            return self._save

    def backup(self,num=2):

        if self._use_num+num>len(self._deque):
            raise RuntimeError("Tried to backup more than the available lines")
        elif self._save is self.not_started:
            raise RuntimeError("Can't backup past the beginning.")
        self._use_save = True
        self._use_num+=num