web-dev-qa-db-ja.com

"EOFではない"のためのPythonの完璧な対応物は何ですか

CまたはPascalでテキストファイルを読むには、EOFまでデータを読むために次のスニペットを常に使います。

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

したがって、Pythonでこれを簡単かつ高速にするにはどうすればよいでしょうか。

98
Allen Koo

ファイルをループして行を読み取ります。

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)が空のバイト文字列を返し始めると繰り返しは停止します。

169
Martijn Pieters

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)
53
dawg

ファイルを開いて1行ずつ読み込むPythonの慣用句は、次のとおりです。

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

ファイルは上記のコードの最後で自動的に閉じられます(with構文がそれを処理します)。

最後に、lineが末尾の改行を保持することに注意する価値があります。これは次のようにして簡単に削除できます。

line = line.rstrip()
16
NPE

「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)

10
user5472996

以下のコードスニペットを使用して、ファイルの最後まで1行ずつ読み取ることができます。

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

    # Do Something

    line = obj.readline()
10
A R

次のコードスニペットを使用できます。 readlines()はファイル全体を一度に読み込み、それを行ごとに分割します。

line = obj.readlines()
1
Aditeya Pandey