【问题标题】:Iterating on a file doesn't work the second time迭代文件第二次不起作用
【发布时间】:2012-05-02 13:45:00
【问题描述】:

我在迭代文件时遇到问题。这是我在解释器上输入的内容和结果:

>>> f = open('baby1990.html', 'rU')
>>> for line in f.readlines():
...  print(line)
... 
# ... all the lines from the file appear here ...

当我再次尝试迭代同一个打开的文件时,我什么也得不到!

>>> for line in f.readlines():
...  print(line)
... 
>>>

根本没有输出。为了解决这个问题,我必须close() 文件然后再次打开它进行阅读!这是正常行为吗?

【问题讨论】:

    标签: python file iteration


    【解决方案1】:

    是的,这是正常行为。你基本上是第一次读到文件的末尾(你可以把它想象成在读磁带),所以除非你重置它,否则你不能再从它读取,通过使用f.seek(0)重新定位到文件的开头,或者关闭它然后再次打开它,这将从文件的开头开始。

    如果您愿意,可以改用with 语法,它会自动为您关闭文件。

    例如,

    with open('baby1990.html', 'rU') as f:
      for line in f:
         print line
    

    一旦这个块执行完毕,文件会自动为你关闭,所以你可以重复执行这个块而无需自己显式关闭文件并以这种方式重新读取文件。

    【讨论】:

    • 如果您使用readlines(),则没有理由读取文件两次。
    • 'U' 在 python 3 中已弃用。
    【解决方案2】:

    当文件对象读取文件时,它使用一个指针来跟踪它的位置。如果您阅读了文件的一部分,然后稍后再返回,它将从您离开的地方继续。如果你读取整个文件,然后返回到同一个文件对象,这就像读取一个空文件一样,因为指针位于文件的末尾,没有什么可以读取的了。您可以使用file.tell() 查看指针在文件中的位置,使用file.seek 设置指针。例如:

    >>> file = open('myfile.txt')
    >>> file.tell()
    0
    >>> file.readline()
    'one\n'
    >>> file.tell()
    4L
    >>> file.readline()
    '2\n'
    >>> file.tell()
    6L
    >>> file.seek(4)
    >>> file.readline()
    '2\n'
    

    此外,您应该知道file.readlines() 读取整个文件并将其存储为列表。这很有用,因为您可以替换:

    for line in file.readlines():
        #do stuff
    file.seek(0)
    for line in file.readlines():
        #do more stuff
    

    与:

    lines = file.readlines()
    for each_line in lines:
        #do stuff
    for each_line in lines:
        #do more stuff
    

    您也可以一次一行地遍历一个文件,而无需将整个文件保存在内存中(这对于非常大的文件非常有用),方法是:

    for line in file:
        #do stuff
    

    【讨论】:

      【解决方案3】:

      文件对象是一个缓冲区。当您从缓冲区读取时,您读取的那部分会被消耗(读取位置向前移动)。当你通读整个文件时,读取的位置在文件的末尾(EOF),所以它什么也不返回,因为没有什么要读取的了。

      如果由于某种原因您必须重置文件对象的读取位置,您可以这样做:

      f.seek(0)
      

      【讨论】:

        【解决方案4】:

        当然。 这是正常和理智的行为。 您可以rewind 文件而不是关闭并重新打开。

        【讨论】:

        • 这对不熟悉读指针概念的用户没有帮助
        猜你喜欢
        • 2022-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-17
        • 1970-01-01
        • 2021-01-13
        • 1970-01-01
        • 2014-01-31
        相关资源
        最近更新 更多