テキストファイルを 1 行毎に処理
これまで
fp = open('sample.txt', 'r') #{ line = fp.readline() # → これと… while line: proc(line) # 1行毎の処理 fp.readline() # → これとが冗長 #} fp.close()
のように readline() が2回出てくる冗長な書き方をしていたが、実はファイルオブジェクトはイテレータなので、#{〜#}の〜部分は、
for line in fp: proc(line) # 1行毎の処理
のようにシンプルに書ける。
バイナリファイルを一定バイト数毎に処理
イテレータとして見た場合、ファイルオブジェクトの持つ next()(for文で暗黙的にコールされる)は、先の例のように行単位で処理される。
これを行単位以外、例えば、一定サイズを読み込む毎に処理させたい場合、イテレータを利用して、
bufsize = 16 # 1回あたりの読み込みサイズ(例は16バイト毎に処理する場合) fp = open('sample.bin', 'rb') for buf in iter(lambda:fp.read(bufsize),''): proc(buf) # 一定サイズ毎の処理 fp.close()
のように書ける。
iter(lambda:fp.read(bufsize),'')にて、bufsizeずつ読み込んだ結果を返すイテレータを作成している。
iter()の第1引数は<iterator>.nextでコールされる関数、第2引数は終了条件で、第1引数で指定した関数が返す結果が第2引数と等しければ終了する。