【发布时间】:2013-03-14 00:56:07
【问题描述】:
要读取一些文本文件,在 C 或 Pascal 中,我总是使用以下 sn-ps 来读取数据,直到 EOF:
while not eof do begin
readline(a);
do_something;
end;
因此,我想知道如何在 Python 中简单快速地做到这一点?
【问题讨论】:
要读取一些文本文件,在 C 或 Pascal 中,我总是使用以下 sn-ps 来读取数据,直到 EOF:
while not eof do begin
readline(a);
do_something;
end;
因此,我想知道如何在 Python 中简单快速地做到这一点?
【问题讨论】:
你可以模仿 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 中除了缺少从读取返回的字节之外还有no eof test。
在 C 中,您可能有:
while ((ch != '\n') && (ch != EOF)) {
// read the next ch and add to a buffer
// ..
}
但是,您不能在 Python 中使用它:
while (line = f.readline()):
# syntax error
因为assignments are not allowed in expressions 在 Python 中(尽管最新版本的 Python 可以使用赋值表达式来模仿这一点,见下文)。
在 Python 中这样做肯定是更多惯用的:
# THIS IS IDIOMATIC Python. Do this:
with open('somefile') as f:
for line in f:
process(line)
更新:从 Python 3.8 开始你也可以使用assignment expressions:
while line := f.readline():
process(line)
即使读取的行是空白的并且一直持续到 EOF,它仍然有效。
【讨论】:
readline() 方式有一个优势:您可以进行细粒度的错误处理,例如捕获UnicodeDecodeError,而惯用的@987654335 则无法做到这一点@迭代。
这个怎么样!让它变得简单!
for line in open('myfile.txt', 'r'):
print(line)
无需浪费额外的行。并且不需要使用with关键字,因为当没有文件对象的引用时文件会自动关闭。
【讨论】:
除了@dawg 的出色答案之外,使用海象运算符(Python >= 3.8)的等效解决方案:
with open(filename, 'rb') as f:
while buf := f.read(max_size):
process(buf)
【讨论】:
遍历文件以读取行:
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()
其中chunk 一次最多可包含文件中的 1024 个字节,当openfileobject.read(1024) 开始返回空字节字符串时,迭代停止。
【讨论】:
line 末尾会有一个换行符。
stdin...所以在我终止进程之前它永远不会有 EOF。但是后来我到达“到现在为止”并且我陷入僵局。我如何检测到这一点而不是死锁?就像没有新行一样,停止读取文件(即使没有 EOF,在我的情况下它永远不会存在)。
虽然上面有“以 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)
【讨论】:
你可以使用下面的代码sn-p。 readlines() 一次读取整个文件并按行拆分。
line = obj.readlines()
【讨论】:
您可以使用下面的代码 sn-p 逐行读取,直到文件末尾
line = obj.readline()
while(line != ''):
# Do Something
line = obj.readline()
【讨论】:
打开文件并逐行读取的 Python 习惯用法是:
with open('filename') as f:
for line in f:
do_something(line)
文件将在上述代码结束时自动关闭(with 结构负责处理)。
最后,值得注意的是line 将保留尾随的换行符。这可以使用以下方法轻松删除:
line = line.rstrip()
【讨论】:
for line in f.readlines(): ...(通常建议的解决方案)不相同。