<p>您可以复制迭代器,然后从该副本还原迭代器。但是,不能复制文件对象。您可以获取枚举数的浅层副本,然后在开始使用复制的枚举数时查找文件的相应部分。你知道吗</p>
<p>但是,最好的方法是编写生成器类,用<code>__next__</code>方法生成行号和行,用<code>mark</code>和<code>recall</code>方法记录并返回到以前记录的状态。你知道吗</p>
<pre><code>class EnumeratedFile:
def __init__(self, fh, lineno_start=1):
self.fh = fh
self.lineno = lineno_start
def __iter__(self):
return self
def __next__(self):
result = self.lineno, next(self.fh)
self.lineno += 1
return result
def mark(self):
self.marked_lineno = self.lineno
self.marked_file_position = self.fh.tell()
def recall(self):
self.lineno = self.marked_lineno
self.fh.seek(self.marked_file_position)
</code></pre>
<p>你可以这样使用它:</p>
<pre><code>from io import StringIO
demo = StringIO('''\
#HEADER1, SOME EXTRA INFO
data first section
1 2
1 233
...
// THIS IS A COMMENT
#HEADER2, SECOND SECTION
452
134
// ANOTHER COMMENT
...
#HEADER3, THIRD SECTION
''')
e = EnumeratedFile(demo)
seen_header2 = False
for lineno, line, in e:
if seen_header2:
print(lineno, line)
assert (lineno, line) == (2, "data first section\n")
break
elif line.startswith("#HEADER1"):
e.mark()
elif line.startswith("#HEADER2"):
e.recall()
seen_header2 = True
</code></pre>