TL;DR
組み込み関数 open()は、指定したモードとエンコーディングでファイルを開きファイルオブジェクト(ファイルを読み書きするオブジェクト)を返す。既存のファイルの読み出し、新しいファイルへの書き込み、既存ファイルへの追記、既存のファイルへの上書きを行う。
組み込み関数 open()のポイント
- 指定したファイルを開き、ファイルオブジェクトを返す
- 通常は、with 文と合わせて使う
- モードを省略すると読み取りでテキストとして開く
- モードは、ファイルのタイプやファイルをどのように操作したいかシステムに知らせる
with によるファイルの自動クローズ
with open('ファイルパス', 'モード', encoding='エンコード') as f:
ファイル処理
第一引数に指定するパスは、拡張子まで記入したファイルを絶対パスか相対パスで指定する。相対パスはカレントディレクトリからのパスである。なお、拡張子は、txt でも md でも、テキストファイルであれば書き込み可能である。
as の後は、任意の名前をつける。encodeing のデフォルトは、プラットフォームに依存する。
モードのデフォルトは、r
なので、読み込みを行う場合は省略可能である。
with を使わずに処理を行えるのだが、with 文を使うと close を省略してくれるので、close の書き忘れを防ぐことができる。したがって with を使うのがよい。
with open('test.md', 'w') as f:
f.write('hello')
with open('test.md', 'r') as f:
a = f.read()
print(a)
# hello
# test.md に書かれた結果が表示される
with 文に対応したオブジェクトは、コンテキストマネージャーと呼ぶ。ファイルや DB 接続などで使う。with 文は「ある処理の前後の処理をまとめて再利用可能」にしてくれる。コードブロックをラップするために使われる。
関連記事:コンテキストマネージャは with 文の前後で処理を実行する
通常、open 関数は with 文と組み合わせて使う。as の後ろに指定した変数にファイルオブジェクトが格納される。
次に示すコードは、コンテキストマネージャを使ったファイル処理。組み込み関数 open()を使ってファイルの書き込みを行う処理を行っている。
with open('test.txt', 'w') as f:
f.write('add text')
# test.txt に「add text」と書き込まれる
f.closed
# True
通常、プログラム言語では、外部ファイルにアクセスする場合、利用後に close 処理を行う。Python においては、with 文を使うと close が省略される。これにより close の書き忘れを防ぐことができる。
with 文のブロックを抜けると、ファイルはクローズされる。次のコードは、書き込みモード内にも関わらず、意図的に書き込みモードを使って例外を発生させている。例外発生時も、ファイルはクローズされる。
with open('test.txt', 'w') as f:
f.read()
# UnsupportedOperation
# 書き込みモードを使うと例外が発生する
ファイルを開いた際は例外発生時であってもファイルはクローズされる。これは、ファイルの破損を防止するためである。
モードの種類
モードを省略すると「読み取り」でテキストとして開く。テキストを読み書きしたい場合は「r」といったように指定する。
モード | 意味 |
---|---|
r | 読み込み用に開く(デフォルト) |
w | 書き込み用に開く。ファイルを切り詰める |
r+ | 読み書き用に開く |
a | 追記用に開く。ファイルが存在する場合は末尾に追記 |
a+ | 読み込みと追記用に開く |
b | バイナリモード |
t | テキストモード(デフォルト) |
「w」は書き込み用としてファイルを開く。ファイルが存在しない場合は新たにファイルが作成される。すでにファイルが存在する場合は、ファイルの中身は消去され、追記されずに上書き保存される。
「x」は、ファイルが存在しない場合は書き込まれ、ファイルが存在する場合は失敗する。
「a」は、ファイルが存在する場合、現在の末尾の後ろへ追記される。
モードの第 2 文字目は、ファイルのタイプを示す。「t」はテキスト、「b」はバイナリという意味である。
次のコードは、ファイルである「test.txt」を開き、何も書き込まずに閉じたので、空ファイルが作られる。
f = open('test.txt', 'w')
f.close()
次に先程作った空ファイルに上書きしてみよう。print によって文字列「hello world」が書き込まれる。
f = open('test.txt', 'w')
print('hello world', file=f)
f.close()
次は、print を使わずに write 関数を使って書き込む。先程書かれた「hello world」の文字は削除され、新たに「this text」という文字がファイルに上書きされた。
f = open('test.txt', 'w')
f.write('this text')
f.close()
x モードを使えば上書きによってファイルを壊すことを防ぐことができる。
f = open('test.txt', 'x')
f.write('xモードで書く')
f.close()
# FileExistsError
例外ハンドラと組み合わせて使うケース。
try:
f = open('test.txt', 'x')
f.write('add text')
except FileExistsError:
print('already exists!')
# already exists!
ファイルの中に書かれている文字数を数えるコード。イテレータを使った例。
txt = ''
f = open('test.txt', 'r')
for i in f:
txt += i
f.close()
len(txt)
# 8
# test.txt には、「add text」と書かれている
ファイルオブジェクトのメソッド
テキストファイルを読むには、以下のメソッドがある。
メソッド | 戻り値 |
---|---|
f.read() | ファイル全体のデータ |
f.readlines() | 1行ずつ分割されたリスト |
f.readline() | 1行ごとのデータ |
read()メソッドは、開いたファイル全体のデータを取得できる。
readlines()メソッドは、次のコードのように行ごとに分割されたリストを返す。返される要素には \n
が含まれる。
with open('test.txt') as f:
a = f.readlines()
print(a)
# ['1行目です\n', '2行目です\n', '最終行です']
readline()でなく、for 文を使うと、改行コードを含まない文字列が1行ずつ表示される。
with open('test.txt') as f:
for i in f:
print(i)
# 1行目です
# 2行目です
# 最終行です
ファイルに書き込むメソッド
メソッド | 戻り値 |
---|---|
f.write() | 指定した文字列を書き込む |
f.writelines() | 指定した文字列リストを一つずつ書き込む |
例えば、writelines メソッドは、ファイルに対し、リストの内容を一つづつ書き込む。要素間にセパレータは入らず、詰めて連結される。
f_list = ["A", "B", "CCC"]
with open('test.txt', 'w') as f:
f.writelines(f_list)
# test.txt に ABCCC と書き込まれた