読者です 読者をやめる 読者になる 読者になる

methaneのブログ

このブログに乗せているサンプルコードはすべてNYSLです。

Python でファイルを直接イテレータとして使うのが適切でない場合

Pythonでサブプロセスと対話する - 西尾泰和のはてなダイアリー

Python のファイルは、通常のファイルの読み込みの効率を考えて大きめ(8192バイト)のバッファリングを行っているので、ソケット通信やパイプで問題になるケースがある。

問題になるケースの一つがファイルオブジェクトをイテレータとして使って行単位の処理をする場合で、

for line in fileobj:
    do_something(line)

のようなコードを書くと、実際には fileobj の中にあるCのFILEから一気に読み込み、その中から改行文字を探して切り出していくので、8192バイト読み出せるかファイルの終端に到達するまでブロックしてしまう。

一方、 file.readline() は、改行を見つけるまで getc() を繰り返すか、(UnixでUniversal Newlineを使わない場合は)fgets を使って、正確に1行を読み出すので、ブロックしないで行を読み出すことが可能だ。

readline() を使って1行ずつの処理をする場合、普段目にすることの無い iter() の第二形態が便利だ。
iter(v, w) という形式で、 callable である v を繰り返し呼び出し、その結果が w でなければそれを返して、 w であれば終了するイテレータになる。

for line in iter(fileobj.readline, ''):
    do_something(line)