我应该如何在 Python 中逐行读取文件?

     2023-02-23     172

关键词:

【中文标题】我应该如何在 Python 中逐行读取文件?【英文标题】:How should I read a file line-by-line in Python? 【发布时间】:2012-07-18 07:41:35 【问题描述】:

在史前时代(Python 1.4)我们做到了:

fp = open('filename.txt')
while 1:
    line = fp.readline()
    if not line:
        break
    print line

在 Python 2.1 之后,我们做到了:

for line in open('filename.txt').xreadlines():
    print line

在我们在 Python 2.3 中获得方便的迭代器协议之前,可以这样做:

for line in open('filename.txt'):
    print line

我见过一些使用更详细的例子:

with open('filename.txt') as fp:
    for line in fp:
        print line

这是未来的首选方法吗?

[edit] 我知道 with 语句可以确保关闭文件...但是为什么文件对象的迭代器协议中没有包含它?

【问题讨论】:

恕我直言,最后一个建议并不比之前的更冗长。它只是做了更多的工作(确保文件在您完成后关闭)。 @azhrei 多了一行,所以客观上更冗长。 我明白你在说什么,但我只是说比较苹果和苹果,你帖子中的倒数第二个建议也需要异常处理代码以匹配最后一个选项的作用。所以在实践中它更加冗长。我想这取决于上下文最后两个选项中哪个是最好的,真的。 【参考方案1】:

以下是首选的原因之一:

with open('filename.txt') as fp:
    for line in fp:
        print line

我们都被 CPython 用于垃圾收集的相对确定性的引用计数方案宠坏了。其他假设的 Python 实现如果使用其他方案来回收内存,则在没有 with 块的情况下不一定会“足够快地”关闭文件。

在这样的实现中,如果您的代码打开文件的速度快于垃圾收集器在孤立文件句柄上调用终结器的速度,您可能会从操作系统收到“打开的文件过多”错误。通常的解决方法是立即触发 GC,但这是一个讨厌的 hack,必须由可能遇到错误的 每个 函数完成,包括库中的函数。真是一场噩梦。

或者您可以只使用with 块。

奖金问题

(如果只对问题的客观方面感兴趣,请立即停止阅读。)

为什么不包含在文件对象的迭代器协议中?

这是一个关于 API 设计的主观问题,所以我有两个部分的主观答案。

在直觉层面上,这感觉是错误的,因为它使迭代器协议做两件独立的事情——遍历行关闭文件句柄——而且制作一个看起来简单的东西通常是个坏主意函数做两个动作。在这种情况下,感觉特别糟糕,因为迭代器以准功能、基于值的方式与文件内容相关联,但管理文件句柄是一项完全独立的任务。将两者无形地压缩到一个动作中,对于阅读代码的人来说是令人惊讶的,并且使推理程序行为变得更加困难。

其他语言基本上也得出了相同的结论。 Haskell 曾短暂使用过所谓的“惰性 IO”,它允许您遍历文件并在到达流的末尾时自动关闭它,但现在几乎普遍不鼓励在 Haskell 和 Haskell 中使用惰性 IO用户大多转向更明确的资源管理,例如 Conduit,其行为更像 Python 中的 with 块。

在技术层面上,您可能希望对 Python 中的文件句柄执行一些操作,如果迭代关闭文件句柄,这些操作将无法正常工作。例如,假设我需要对文件进行两次迭代:

with open('filename.txt') as fp:
    for line in fp:
        ...
    fp.seek(0)
    for line in fp:
        ...

虽然这是一个不太常见的用例,但请考虑这样一个事实,即我可能刚刚将底部的三行代码添加到最初具有顶部三行的现有代码库中。如果迭代关闭了文件,我将无法做到这一点。因此,将迭代和资源管理分开可以更容易地将代码块组合成一个更大的、工作的 Python 程序。

可组合性是语言或 API 最重要的可用性特性之一。

【讨论】:

+1 因为它解释了我对操作的评论中的“何时”;-) 即使使用替代实现,with 处理程序也只会给您快速连续打开数百个文件的程序带来问题。大多数程序可以毫无问题地使用悬空文件引用。除非您禁用它,否则最终 GC 将在某个时候启动并清除文件句柄。 with 确实让您高枕无忧,因此它仍然是最佳实践。 @DietrichEpp:也许“悬空文件引用”不是正确的词,我真正的意思是不再可访问但尚未关闭的文件句柄。在任何情况下,GC 将在收集文件对象时关闭文件句柄,因此只要您没有对文件对象的额外引用并且您没有禁用 GC 并且您没有快速打开许多文件连续,由于没有关闭文件,您不太可能得到“打开的文件太多”。 是的,这正是我所说的“如果您的代码打开文件的速度比垃圾收集器在孤立文件句柄上调用终结器的速度更快”的意思。 使用 with 的更大原因是,如果你不关闭文件,它不一定会立即被写入。【参考方案2】:

是的,

with open('filename.txt') as fp:
    for line in fp:
        print line

是要走的路。

这不是更冗长。它更安全。

【讨论】:

【参考方案3】:

如果你被多余的行关闭了,你可以像这样使用包装函数:

def with_iter(iterable):
    with iterable as iter:
        for item in iter:
            yield item

for line in with_iter(open('...')):
    ...

在 Python 3.3 中,yield from 语句会更短:

def with_iter(iterable):
    with iterable as iter:
        yield from iter

【讨论】:

调用函数 xreadlines.. 并将其放入一个名为 xreadlines.py 的文件中,然后我们回到 Python 2.1 语法:-) @thebjorn:也许,但是您引用的 Python 2.1 示例在替代实现中对未关闭的文件处理程序并不安全。从未关闭的文件处理程序中安全读取的 Python 2.1 文件至少需要 5 行。【参考方案4】:
f = open('test.txt','r')
for line in f.xreadlines():
    print line
f.close()

【讨论】:

这并不能真正回答问题

在 Go 中逐行读取文件

...题描述】:我在Go中找不到file.ReadLine函数。我可以弄清楚如何快速写一个,但我只是想知道我是否在这里忽略了一些东西。如何逐行读取文件?【问题讨论】:从Go1.1开始,bufio.Scanner是执行此操作的最佳方式。【参考方案1】:... 查看详情

如何在 Julia 中逐行读取文件?

】如何在Julia中逐行读取文件?【英文标题】:HowtoreadafilelinebylineinJulia?【发布时间】:2020-01-2920:32:14【问题描述】:如何打开文本文件并逐行读取?我对两种不同的情况感兴趣:一次获取数组中的所有行。一次处理每一行。对... 查看详情

如何在 React 中逐行读取磁盘中的大 csv 文件?

】如何在React中逐行读取磁盘中的大csv文件?【英文标题】:HowtoreadbigcsvfilefromdisklinebylineinReact?【发布时间】:2019-11-0108:18:04【问题描述】:我有一个大数据类型的csv文件。我想逐行阅读。我不想内存溢出。我正在寻找这个,但... 查看详情

Python:如何在 numpy 数组中逐行读取?

】Python:如何在numpy数组中逐行读取?【英文标题】:Python:Howtoreadlinebylineinanumpyarray?【发布时间】:2016-06-0508:11:13【问题描述】:我想知道我们可以在数组中逐行读取。例如:array([[0.28,0.22,0.23,0.27],[0.12,0.29,0.34,0.21],[0.44,0.56,0.51,0.... 查看详情

在 Swift 中逐行读取文本文件?

...了我的代码,并且应用程序显示了整个文本文件的内容。如何逐行显示并多次调用该行?TextFile.txt包含以下内容:1.Banana2.Apple3.pear4.strawberry5.blueberry6.blackc 查看详情

如何在 C# 中逐行读取 CMD 输出结果

】如何在C#中逐行读取CMD输出结果【英文标题】:HowtoReadCMDoutputresultslinebylineinC#【发布时间】:2021-08-0809:59:28【问题描述】:我想打开.bat文件,为此我使用cmd并为参数提供输入,最后我收到整个输出结果,但我只想获得最后一个... 查看详情

在 C# 中逐行读取文件

】在C#中逐行读取文件【英文标题】:ReadingafilelinebylineinC#【发布时间】:2010-11-1906:20:55【问题描述】:我正在尝试读取一些文本文件,其中每一行都需要处理。目前我只是使用StreamReader,然后单独读取每一行。我想知道是否有... 查看详情

如何从 C++ 中的文本文件中逐行读取整数? [复制]

】如何从C++中的文本文件中逐行读取整数?[复制]【英文标题】:Howtoreadintegerslinebylinefromatextfileinc++?[duplicate]【发布时间】:2020-02-2420:10:58【问题描述】:所以我有一个关于图表的问题,我必须从输入文件中读取多个案例并检查... 查看详情

如何在目标c中逐行解析JSON文件

】如何在目标c中逐行解析JSON文件【英文标题】:HowtoparseaJSONfilelinebylineinobjectivec【发布时间】:2018-01-0115:33:51【问题描述】:我正在处理非常大的JSON文件,因此我不想读取整个文件然后迭代和解析每个数据条目。相反,我想迭... 查看详情

在 Swift 中逐行读取文件/URL

】在Swift中逐行读取文件/URL【英文标题】:Readafile/URLline-by-lineinSwift【发布时间】:2014-08-2605:15:45【问题描述】:我正在尝试读取NSURL中给出的文件并将其加载到数组中,其中项目由换行符\\n分隔。这是我目前的做法:varpossList:NS... 查看详情

如何在 Java 中逐行读取文本文件并分隔每一行的内容?

】如何在Java中逐行读取文本文件并分隔每一行的内容?【英文标题】:Howdoyoureadatextfile,linebyline,andseparatecontentsofeachlineinJava?【发布时间】:2015-10-1401:21:23【问题描述】:我想知道如何读取文件并扫描每一行,但将每一行的内容... 查看详情

在 Java 中逐行读取和写入大文件的最快方法

】在Java中逐行读取和写入大文件的最快方法【英文标题】:FastestWayToReadandWriteLargeFilesLineByLineinJava【发布时间】:2012-10-2018:41:18【问题描述】:我一直在寻找在内存有限(约64MB)的Java中再次读取和写入大文件(0.5-1GB)的最快方... 查看详情

在 VBA 中逐行读取/解析文本文件

】在VBA中逐行读取/解析文本文件【英文标题】:Read/ParsetextfilelinebylineinVBA【发布时间】:2012-07-1617:45:47【问题描述】:我正在尝试使用VBA解析文本文档并返回文本文件中给出的路径。例如,文本文件如下所示:*Blahblahinstructions*B... 查看详情

在 Fortran 中逐行读取逗号分隔的文本文件

】在Fortran中逐行读取逗号分隔的文本文件【英文标题】:Readingacomma-delimitedtextfileline-by-lineinFortran【发布时间】:2011-09-2209:31:39【问题描述】:我是Fortran新手。我希望能够读取文本文件并将其内容保存在各个变量中。我找到了一... 查看详情

在nodejs中逐行读取文件没有简单的方法吗? [复制]

】在nodejs中逐行读取文件没有简单的方法吗?[复制]【英文标题】:Noeasywaytoreadafilelinebylineinnodejs?[duplicate]【发布时间】:2019-03-1812:16:15【问题描述】:我正在用nodejs编写一个小解析器,它将给定的汇编语言翻译成二进制代码。... 查看详情

在一个非常大的文件中逐行读取特定的行

】在一个非常大的文件中逐行读取特定的行【英文标题】:Readingaparticularlinebylinenumberinaverylargefile【发布时间】:2012-09-2718:06:13【问题描述】:文件不适合内存。它超过100GB,我想按行号访问特定行。在到达之前我不想逐行数数... 查看详情

在 C 中逐行浏览文本文件

】在C中逐行浏览文本文件【英文标题】:GoingthroughatextfilelinebylineinC【发布时间】:2012-03-0115:24:32【问题描述】:我一直在为我的CIS课程做一个小练习,并且对C用于读取文件的方法感到非常困惑。我真正需要做的就是逐行读取文... 查看详情

在批处理文件中逐行读取txt

】在批处理文件中逐行读取txt【英文标题】:Readatxtlinebylineinabatchfile【发布时间】:2012-05-0403:47:56【问题描述】:这是我的问题。我有一个包含100个不同视频名称的txt文件(示例):abc.mpgdef.mpgghi.mpgxyz.mpg我想使用一些命令一个... 查看详情