什么是 Python 中完美的对应物"while not EOF"



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

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

因此,我想知道如何在Python中简单而快速地完成此操作?

遍历文件读取行:

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

File对象是可迭代的,并且在EOF之前生成行。使用file对象作为可迭代对象使用缓冲区来确保高性能读取。

你可以用stdin做同样的事情(不需要使用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()

其中chunk每次最多包含1024个字节,当openfileobject.read(1024)开始返回空字节字符串时,迭代停止。

你可以在Python中模仿C语言的习惯用法。

要读取最多max_size (>0)字节的缓冲区,您可以这样做:

with open(filename, 'rb') as f:
    while True:
        buf = f.read(max_size)
        if buf == 0:
            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

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

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

该文件将在上述代码结束时自动关闭(with结构负责此操作)。

最后,值得注意的是line将保留尾随换行符。可以使用:

将其删除。
line = line.rstrip()

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

line = obj.readline()
while(line != ''):
    # Do Something
    line = obj.readline()

虽然上面有"用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

或在raw_input()提示符下按Ctrl-Z (Windows, Ctrl-Z Linux)

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

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

可以使用下面的代码片段。Readlines()一次读取整个文件并逐行拆分。

line = obj.readlines()

这个怎么样!简单点!

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

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

最新更新