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()
ファイルオブジェクトは反復可能であり、EOFまで行を生成します。ファイルオブジェクトを反復可能として使用すると、バッファを使用してパフォーマンスの高い読み取りが保証されます。
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
、次のようにします。
with open(filename, 'rb') as f:
while True:
buf = f.read(max_size)
if not buf:
break
process(buf)
または、テキストファイルを1行ずつ:
# warning -- not idiomatic Python! See below...
with open(filename, 'rb') as f:
while True:
line = f.readline()
if not line:
break
process(line)
読み取りから返されるバイトがないこと以外にPythonにはeofテストwhile True / break
がないため、構文を使用する必要があります。
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()
以下のコードスニペットを使用して、ファイルの終わりまで1行ずつ読み取ることができます
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
またはプロンプトCtrl-Zでを押しraw_input()
ます(Windows、Ctrl-ZLinux)
@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
また、ファイルオブジェクトの参照がない場合、ファイルは自動的に閉じられるため、キーワードを使用する必要はありません。