Python:使用f.next()进行迭代时倒退文件中的一行

发布于 2021-01-29 14:58:24

当您使用f.next()遍历文件时,Python的f.tell无法正常工作:

>>> f=open(".bash_profile", "r")
>>> f.tell()
0
>>> f.next()
"alias rm='rm -i'\n"
>>> f.tell()
397
>>> f.next()
"alias cp='cp -i'\n"
>>> f.tell()
397
>>> f.next()
"alias mv='mv -i'\n"
>>> f.tell()
397

看起来它为您提供了缓冲区的位置,而不是您通过next()获得的位置。

以前,我在使用readline()遍历文件时曾使用过seek /
tell技巧来倒退一行。使用next()时是否有一种方法可以快退一行?

关注者
0
被浏览
75
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    否。我将创建一个适配器,该适配器在很大程度上转发所有呼叫,但在执行时保留最后一行的副本,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()
    

    扩展到允许您以不止一个值进行备份的方式并不难。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看