142

要在 C 或 Pascal 中读取一些文本文件,我总是使用以下代码片段来读取数据,直到 EOF:

while not eof do begin
  readline(a);
  do_something;
end;

因此,我想知道如何在 Python 中简单快速地做到这一点?

4

8 回答 8

225

循环文件以读取行:

with open('somefile') as openfileobject:
    for line in openfileobject:
        do_something()

文件对象是可迭代的,并且在 EOF 之前产生行。将文件对象用作可迭代对象使用缓冲区来确保高性能读取。

您可以对标准输入执行相同操作(无需使用raw_input()

import sys

for line in sys.stdin:
    do_something()

为了完成图片,可以通过以下方式完成二进制读取:

from functools import partial

with open('somefile', 'rb') as openfileobject:
    for chunk in iter(partial(openfileobject.read, 1024), b''):
        do_something()

wherechunk一次将包含来自文件的最多 1024 个字节,并且当openfileobject.read(1024)开始返回空字节字符串时迭代停止。

于 2013-03-24T14:26:23.057 回答
74

你可以模仿 Python 中的 C 习语。

要读取最多max_size字节数的缓冲区,您可以执行以下操作:

with open(filename, 'rb') as f:
    while True:
        buf = f.read(max_size)
        if not buf:
            break
        process(buf)

或者,逐行的文本文件:

# warning -- not idiomatic Python! See below...
with open(filename, 'rb') as f:
    while True:
        line = f.readline()
        if not line:
            break
        process(line)

您需要使用while True / break构造,因为除了读取返回的字节不足之外,Python中没有 eof 测试。

在 C 中,您可能有:

while ((ch != '\n') && (ch != EOF)) {
   // read the next ch and add to a buffer
   // ..
}

但是,您不能在 Python 中使用它:

 while (line = f.readline()):
     # syntax error

因为在 Python中的表达式中不允许赋值(尽管最新版本的 Python 可以使用赋值表达式来模仿这一点,见下文)。

在 Python 中这样做当然更惯用:

# THIS IS IDIOMATIC Python. Do this:
with open('somefile') as f:
    for line in f:
        process(line)

更新:从 Python 3.8 开始,您还可以使用赋值表达式

 while line := f.readline():
     process(line)

即使读取的行是空白的并且一直持续到 EOF,这仍然有效。

于 2013-03-24T14:40:18.827 回答
19

打开文件并逐行读取的 Python 习惯用法是:

with open('filename') as f:
    for line in f:
        do_something(line)

该文件将在上述代码的末尾自动关闭(with构造负责)。

最后,值得注意的是,line将保留尾随换行符。这可以使用以下方法轻松删除:

line = line.rstrip()
于 2013-03-24T14:27:04.153 回答
14

您可以使用下面的代码片段逐行读取,直到文件结尾

line = obj.readline()
while(line != ''):

    # Do Something

    line = obj.readline()
于 2014-10-27T11:53:56.900 回答
11

虽然上面有“以python方式做”的建议,但如果一个人真的想拥有一个基于EOF的逻辑,那么我想使用异常处理是一种方法——

try:
    line = raw_input()
    ... whatever needs to be done incase of no EOF ...
except EOFError:
    ... whatever needs to be done incase of EOF ...

例子:

$ echo test | python -c "while True: print raw_input()"
test
Traceback (most recent call last):
  File "<string>", line 1, in <module> 
EOFError: EOF when reading a line

Ctrl-Zraw_input()提示时按(Windows、Ctrl-ZLinux)

于 2015-10-21T19:03:24.850 回答
2

除了@dawg 的出色答案之外,使用海象运算符(Python >= 3.8)的等效解决方案:

with open(filename, 'rb') as f:
    while buf := f.read(max_size):
        process(buf)
于 2020-07-30T11:49:55.110 回答
1

您可以使用以下代码片段。readlines() 一次读取整个文件并按行拆分。

line = obj.readlines()
于 2015-03-08T16:33:42.833 回答
0

这个怎么样!让它变得简单!

for line in open('myfile.txt', 'r'):
    print(line)

无需浪费额外的线路。并且不需要使用with关键字,因为当没有文件对象的引用时文件会自动关闭。

于 2021-06-05T13:27:58.977 回答