【问题标题】:Explanation for one read operation per open() statement behavior?每个 open() 语句行为的一个读取操作的解释?
【发布时间】:2026-01-16 18:45:01
【问题描述】:

最近我在 Python 中遇到了一个带有 open() 语句的奇怪行为。 以下代码仅返回第一个读取语句的输出,具有一个空行列表。

input_csv = []
with open(self.path, 'r') as f:  # Opening the CSV
    r = csv.DictReader(f)
    for row in r:
        input_csv.append(row)  # Storing its contents in a dictionary for later use
    lines = f.readlines()  # Reading it in as a list too
    f.close()

将其拆分为两个 open () 语句时,会根据需要返回对象。

input_csv = []
with open(self.path, 'r') as f:  # Opening the CSV
    r = csv.DictReader(f)
    for row in r:
        input_csv.append(row)  # Storing its contents in a dictionary for later use
    f.close()

with open(self.path, 'r') as f:  # Opening the CSV
    lines = f.readlines()  # Reading it in as a list too
    f.close()

为什么f变量在第一条语句中只使用了一次?

非常感谢

【问题讨论】:

  • DictReader 就像readlines() 一样耗尽文件。一旦打开的文件到达末尾,就没有更多数据要读取,除非像您所做的那样,您再次open()它。
  • 当您从文件中读取数据时,系统会移动“指针”,通知系统必须读取下一个数据在文件中的哪个位置。当您读取完整文件时,指针会显示文件结尾,您必须重新打开文件或使用f.seek(0) 将指针移动到文件开头。

标签: python csv oop input io


【解决方案1】:

如果您查看用于DictReader().readercsv.reader() 的文档:

返回一个读取器对象,它将遍历给定 csvfile 中的行。 csvfile 可以是任何支持迭代器协议的对象,并且每次调用其__next__() 方法时都会返回一个字符串...

因此,它使用类似文件的对象的行为,每次迭代本质上都是f.readline()。一个操作,它也推进文件中的当前位置......直到达到 EOF,当迭代引发 StopIteration 异常。这与您在尝试时会观察到的行为相同:

with open(self.path, 'r') as f:
    for l in f:
        pass  # each line was read
    print(f.readlines())

您可以添加print(f.tell()) 以查看执行每一行时位置如何变化。

如果您(重新)打开一个新文件,则从位置0(再次)开始。如果您已经通读过一次并想再次使用相同的句柄,则需要返回到文件的开头:f.seek(0)

注意:您确实不需要在使用with 的托管上下文中执行f.close()。一旦你离开它,它会为你关闭文件句柄。

【讨论】:

    最近更新 更多