連載
» 2020年02月04日 05時00分 公開

Pythonチートシート:[Pythonチートシート]ファイル操作編

ファイルのオープンとクローズ、with文を使った書き方からテキストファイルやバイナリファイルの読み書き、structモジュールまでをギュッとまとめた。

[かわさきしんじ,Deep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「Pythonチートシート」のインデックス

連載目次

 ファイルを扱う上での基本となる組み込みのopen関数、with文との組み合わせ、テキストファイルの読み書き、バイナリファイルの読み書きについて見ていこう。

 なお、ファイルの操作については以下の記事も参考にしてほしい。

ファイルのオープンとクローズ

 ファイルは組み込みのopen関数を用いてオープンし、それに対して読み込み、書き込みを行った後、クローズするのが通常のファイル操作の手順となる。その流れを以下にまとめる。

file = open(ファイル名, モード, その他の引数# ファイルのオープン
content = file.read()  # 読み込みの例
file.write('foo'# 書き込みの例
file.close()  # ファイルのクローズ

ファイル操作の流れ

 あるいは、with文を使用することで、ファイルのクローズを自動的に行うことも可能だ。例外処理

with open(ファイル名, モード, その他の引数) as file:  # ファイルのオープン
    content = file.read()  # 読み込みの例
    file.write('foo'# 書き込みの例。ブロック終了後にファイルはクローズされる

with文を利用したファイル操作の流れ

 with文でファイルを扱うときには、そのブロックが終了すると、ファイルが自動的にクローズされる。with文はファイル操作中に例外が発生しても、そのクローズが確実に行えるので、こちらの使い方が推奨されている。

 ファイルのオープンに使用する組み込みのopen関数の構文は次のようになっている。

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

open関数

 それぞれのパラメーターの意味は以下の通り。

  • file:ファイル名またはファイル記述子を与える
  • mode:ファイルをオープンするモード。デフォルト引数値は'r'で、これはファイルをテキストモードで読み込み用にオープンすることを意味する('rt'と同じ)。詳細は後述
  • buffering:バッファリング方法の指定。指定可能な値は0(バッファリングを行わない)、1(1は行単位のバッファリングを行う。テキストファイルでのみ有効)、1以上の整数(バッファサイズをバイト単位で指定)となっている
  • encoding:テキストファイルの読み書きで使用するエンコーディングを指定
  • errors:テキストファイルの読み書きでエンコード/デコードに失敗したときの対応を指定。指定可能な値は'strict'(ValueError例外を発生)、'ignore'(無視)など
  • newline:テキストファイルの読み書きにおけるユニバーサル改行モードの動作を制御する。詳細はnewlineパラメーターの説明を参照のこと
  • closefd:fileパラメーターにファイル記述子が与えられた場合に、ファイルクローズ時にそのファイル記述子(が参照するファイル)もクローズするかどうかを指定する。Trueを指定すると元のファイル記述子もクローズされ、Falseを指定すると元のファイル記述子はオープンされたままとなる
  • opener:ファイルのオープンに利用する呼び出し可能オブジェクトを指定する

 modeパラメーターには以下を指定できる。

  • 'r':読み込み用にオープン
  • 'w':書き込み用にオープン
  • 'x':ファイルを新規に作成して、書き込み用にオープン。指定したファイルが既にあればエラーとなる
  • 'a':追加書き込み用にオープン
  • 't':テキストファイルをオープン(テキストモード)
  • 'b':バイナリファイルをオープン(バイナリモード)
  • '+':'r'/'w'/'a'/'x'に付加して、ファイルを更新用にオープン(読み込み/書き込み両用でオープン)

 '+'は'r'、'w'、'a'、'x'と一緒に指定して、そのファイルを読み書き両用にオープンする。

  • 'r+':既存ファイルの先頭をファイル位置とする。指定した名前のファイルがなければエラーとなる
  • 'w+':ファイルを新規に作成するか、既存のファイルをオープンして、その内容を全て削除する。ファイルの先頭がファイル位置になる
  • 'a+':ファイルを新規に作成するか、既存のファイルをオープンして、末尾をファイル位置とする(新規ファイルの場合はファイル末尾=ファイル先頭となる)
  • 'x+':ファイルを新規作成して、そのファイルを読み書き両用にオープンする

テキストファイルの読み書き

 open関数でmodeパラメーターに'rt'(または単に'r')を指定するとテキストファイルを読み込み用にオープンできる。modeパラメーターに'wt'などを指定すると、テキストファイルを書き込み用にオープンできる。Pythonのテキストファイルは「文字列の読み書き」を行う。整数など、文字列以外のものは書式化して、文字列に埋め込む必要があるので注意しよう。

 テキストファイルを読み込むメソッドとしては以下がある。

  • readメソッド:ファイルの内容を全て読み込む。戻り値は1つの文字列
  • readlineメソッド:ファイルから1行を読み込む。戻り値は1つの文字列
  • readlinesメソッド:ファイルの内容を全て読み込む。戻り値は、各行を要素とするリスト

 これらのメソッドはファイルの末尾まで読み込みが終わると、その後に呼び出しを行うと空文字列を返す。空文字列は「偽」として扱われるので、これを使ってループの繰り返しを制御できる(ファイル中の空行には改行文字のみが含まれるので、空文字列とはならない)。また、open関数の戻り値であるファイルオブジェクト自身はその各行を返送する反復可能オブジェクトとしても使用できる。

 テキストファイルに書き込みを行うメソッドとしては以下がある。

  • writeメソッド:引数に渡した「文字列」をファイルへ書き込む。戻り値は書き込んだ文字数
  • writelinesメソッド:引数に渡した反復可能オブジェクトの内容をファイルへ書き込む。戻り値はなし。各要素の末尾に改行文字が追記されることはないので、改行したいときには末尾に改行を自分で追加する必要がある

 これらのメソッドでは、sizeパラメーター(読み込む文字数)やhintパラメーター(読み込む行数。readlinesメソッドの場合)を指定できる。

 modeパラメーターに'wt'を指定した場合を例として、これらのメソッドの使い方を以下に示す。

with open('foo.txt', 'wt') as file:  # 'foo.txt'ファイルを書き込み用にオープン
    mylist = ['foo', '', 'bar']
    for num, item in enumerate(mylist):
        file.write(f'{num}: {item}\n'# f文字列に行カウントを埋め込み
    # writelinesメソッドでは各要素の末尾に改行文字が追加されないので自分で追加
    file.writelines([item.upper() + '\n' for item in mylist])

file = open('foo.txt')
print(file.read())  # ファイルの内容を全て読み込む

file.seek(0# seekメソッドに0を渡してファイル先頭をファイル位置にする
line = file.readline()  # ファイルの内容を1行ずつ読み込む
while line:  # 変数lineの内容が空文字列となるまで(ファイル末尾となるまで)
    print(line, end=''# 各要素には改行文字が含まれている
    line = file.readline()  # 次の行を読み込む

file.seek(0)
lines = file.readlines()  # 全ての行を読み込む
for line in lines:  # その内容をfor文でループ
    print(line, end='')

file.seek(0)
for line in file:  # ファイルオブジェクトを使って繰り返し
    print(line, end='')

file.close()  # 使い終わったらファイルを閉じる

テキストファイルの読み書きの例

 上の例では、ファイルオブジェクトのseekメソッドを用いて、各行の表示が終わった後にもう一度ファイル先頭にファイル位置を移動するようにしている。ファイルオブジェクトが持つその他のメソッドについてはPythonのドキュメント「io --- ストリームを扱うコアツール」にある「TextIOBase」などを参照のこと。例えば、現在のファイル位置を知る「tellメソッド」などがある。

バイナリファイルの読み書き

 バイナリファイルの読み書きを行うには、open関数のmodeパラメーターに'b'を付加する。'rb'ならバイナリファイルの読み込みを、'wb'ならバイナリファイルへの書き込みを意味する。バイナリファイルの内容はbytes型のデータとしてやりとりをする。

 バイナリファイルの読み込みを行うメソッドには以下がある。

  • readメソッド:バイナリファイルの内容を全て読み込む。sizeパラメーターに値を指定した場合、最大で指定したバイト数を読み込む
  • readallメソッド:バイナリファイルの内容を全て読み込む
  • readintoメソッド:引数に渡したbytearrayオブジェクトに、読み出した内容を書き込む

 バイナリファイルへの書き込みを行うメソッドには以下がある。

  • writeメソッド:バイナリファイルにバイトオブジェクトを書き込む

 読み込んだデータはbytes型(またはbytearray型)のオブジェクトなので、それらを使用する際には何らかの型のデータへと変換する必要がある。例えば、文字列ならdecodeメソッドでそれらを文字列にデコードできる。逆に書き込みを行う際には、元のデータをbytes型のデータに変換する必要もある。例えば、文字列であれば、encodeメソッドでbytes型のデータに変換できる。整数ならto_bytesメソッド、from_bytesメソッドでbytes型の値との変換が行える。

 以下にバイナリファイルの読み書きの例を示す。

with open('foo.bin', 'wb') as file:
    mystr = 'Hello Python'
    size = file.write(mystr.encode())  # 文字列をエンコードして書き込み
    mynumbers = [x.to_bytes(2, 'little') for x in [0, 1, 2]]  # bytes型に変換
    for item in mynumbers:
        file.write(item)  # bytes型に変換された整数値を書き込み

file = open('foo.bin', 'rb')
tmp = file.read(size)
print(tmp.decode())
tmp = file.read(2# 2バイトを読み込み
while tmp:
    print(int.from_bytes(tmp, 'little'))
    tmp = file.read(2)

file.close()

バイナリファイルの読み書きの例

 ここではファイルをバイナリ書き込みモードでオープンした後、文字列'Hello Python'をencodeメソッドでエンコードしたものをwriteメソッドで書き込んでいる。次に、リスト[0, 1, 2]の各要素をint型のto_bytesメソッドでbytesオブジェクトに変換し、それらをやはりwriteメソッドで書き込んでいる。

 to_bytesメソッドを呼び出す際には第1引数にbytesオブジェクトに変換後のbytesオブジェクトのバイトサイズを(ここでは2バイトのデータに変換)、第2引数にバイトオーダー(bytesオブジェクトに変換された整数の各バイトの並び順)を指定する。ここでは'little'(リトルエンディアンと呼ばれるバイトオーダー)を指定している。書き込んだデータを読み込んで復元する際にはバイトオーダーが一致している必要がある点には注意が必要だ。

 バイナリファイルからの読み込みでは、文字列の書き込み時に得たwriteメソッドの戻り値(書き込んだバイト数)を使って、バイナリファイルから文字列に相当するバイトデータを読み込み、それをdecodeメソッドで復元している。その後は、while文を使って2バイトずつ読み込んで、今度はint型のfrom_bytesクラスメソッドを使って、読み込んだバイトデータを整数に変換している。

structモジュール

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。