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まで行を生成します。ファイルオブジェクトをイテラブルとして使用すると、バッファを使用してパフォーマンスの高い読み取りを保証できます。
標準入力でも同じことができます(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 test がないため、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では確かにもっと慣用句です。
# THIS IS IDIOMATIC Python. Do this:
with open('somefile') as f:
for line in f:
process(line)
ファイルを開いて1行ずつ読み込むPythonの慣用句は、次のとおりです。
with open('filename') as f:
for line in f:
do_something(line)
ファイルは上記のコードの最後で自動的に閉じられます(with
構文がそれを処理します)。
最後に、line
が末尾の改行を保持することに注意する価値があります。これは次のようにして簡単に削除できます。
line = line.rstrip()
「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-Z Linux)
以下のコードスニペットを使用して、ファイルの最後まで1行ずつ読み取ることができます。
line = obj.readline()
while(line != ''):
# Do Something
line = obj.readline()
次のコードスニペットを使用できます。 readlines()はファイル全体を一度に読み込み、それを行ごとに分割します。
line = obj.readlines()