この記事では、Pythonのopen関数を使ってソースコード内からファイルを読み書きする方法を解説します。
プログラミングをしていると外部に処理結果を保存したり、外部のデータを読み込んでソースコード内で使用したい場合がよくあります。
Pythonでファイルを読み込んだり書き込んだりするには、open
関数を使って生成したファイルオブジェクトを通して行います。
それでは、ファイルを読み書きする方法を見ていきましょう!
ファイル操作の基本
ファイルの読み書きは、以下のような手順で行われます。
STEP1. ファイルを開く
ファイルを開くには、open()
関数を使います。open()
関数は、引数に「パス」と「モード」を受け取り、モードに対応したファイルオブジェクトを返します。
ファイルオブジェクト名 = open('パス', 'モード')
オプションでエンコーディングを指定することもできます。
ファイルオブジェクト名 = open('パス', 'モード', 'エンコーディング')
モード一覧
指定できるモードには、以下のようなものがあります。
文字 | モード |
---|---|
r | 読み込み用で開く(デフォルト) |
w | 書き込み用で開く |
x | ファイルが存在しなければ生成し、存在したらエラーとなる |
a | 書き込み用で開く。すでにファイルが存在する場合は末尾に追加する |
b | バイナリモードで開く |
t | テキストモードで開く(デフォルト) |
+ | 更新用で開く |
モードを省略すると「読み込み用(r) + テキストモード(t)」としてファイルを開きます。
f = open('パス')
「書き込み用(w) + テキストモード(t)」でファイルを開くには、
f = open('パス', 'w')
# テキストモードを明示的に指定することもできるが必要はない
f = open('パス', 'wt')
「読み込み用(r) + バイナリモード(b)」でファイルを開くには、
f = open('パス', 'rb')
という感じで記述します。
STEP2. 読み書き
生成したファイルオブジェクトからファイルを操作することができます。
指定したモードに対応したファイルオブジェクトが生成されるのでモードによって使用できるメソッドが異なります。
例えば、書き込み用で開いた場合は、write()
などの書き込むためのメソッドが使用可能。
f = open('パス', 'w')
f.write('書き込む内容')
読み込み用で開いた場合は、read()
などの読み込むためのメソッドが使える。
f = open('パス', 'r')
f.read()
モード別のファイルオブジェクトの使い方は後述します。
STEP3. ファイルを閉じる
使い終わったファイルは必ず閉じる必要があります。
ファイルを閉じるにはファイルオブジェクトのclose()
メソッドを呼び出します。
ファイルオブジェクト.close()
しかし、この方法では閉じ忘れてしまう可能性があるのでwith
文を使った方が安全です。with
文は、以下のように記述します。
with open('パス', 'モード') as ファイルオブジェクト名:
# なんらかの処理
with
文を使うことでブロックを抜けた際に勝手にファイルを閉じてくれます。
それでは、モード別の使い方を見ていきましょう!
ファイルを読み込む 'r'
open()
関数のモードに'r'
を指定するか、省略することでファイルを読み込むためのファイルオブジェクトを生成できます。
読み込み用のファイルオブジェクト = open('パス', 'r')
指定したパスのファイルが存在しなければFileNotFoundError
が送出されます。
それでは、開いたファイルから内容を読み込む方法を見ていきましょう!
まとめて取得:readメソッド
read()
メソッドを使うことで内容をまとめてを読み取ることができます。
with open('test.txt', 'r') as f:
data = f.read()
print(data)
実行結果
one
two
three
読み込むファイルが大きすぎる場合は危険なので分割して読み出しましょう。引数に整数を指定することで読み込む文字数を指定することができます。
with open('test.txt', 'r') as f:
data1 = f.read(4)
data2 = f.read(4)
data3 = f.read()
print(data1)
print(data2)
print(data3)
実行結果
one
two
three
改行も1文字としてカウントされる点に注意。
1行ずつ取得:readlineメソッド
readline()
メソッドを使うことで1行ずつ(改行まで)読み取ることができます。引数を指定することで読み出す文字数を指定できます。
with open('test.txt', 'r') as f:
line1 = f.readline()
line2 = f.readline()
line3 = f.readline(5)
line4 = f.readline()
print(f'line1: {line1}')
print(f'line2: {line2}')
print(f'line3: {line3}')
print(f'line4: {line4}')
実行結果
line1: one
line2: two
line3: three
line4:
for
文を使うことでファイルの内容を1行ずつ取得することができます。
with open('test.txt', 'r') as f:
# ファイルの内容を1行ずつ取り出す
for line in f:
print(line)
実行結果
one
two
three
ファイル内の改行文字も読み込みprint()
関数で出力しているので行間が余分に空いてしまっています。
リストとして取得:readlinesメソッド
readlines()
メソッドを使うことで全ての行をリスト形式で読み出せます。ちなみに、ファイルオブジェクトをリストに変換することでも同様の処理が可能です。
with open('test.txt', 'r') as f:
lines = f.readlines()
# lines = list(f)でも同じ
print(lines)
実行結果
['one\n', 'two\n', 'three']
ファイルに書き込む 'w'
open()
関数のモードに'w'
を指定することでファイルを書き込むためのファイルオブジェクトを生成することができます。
書き込み用のファイルオブジェクト = open('パス', 'w')
指定したパスのファイルが存在しない場合はその名前のファイルが新しくが生成され、存在する場合は上書きされます。
それでは、開いたファイルに書き込む方法を見ていきます。
文字列を書き込む:writeメソッド
write()
メソッドを使うことで引数に渡された文字列を書き込むことができます。文字列型ではないデータを書き込みたい場合は、文字列型に変換する必要があります。
num = 7532
# 文字列に変換
s = str(num)
with open('test.txt', 'w') as f:
f.write(s)
以下のファイルが生成されました。
リストの書き込み:writelinesメソッド
writelines()
メソッドを使うことで引数に指定したリストをファイルに書き込むことができます。
l = ['いち', 'に', 'さん']
with open('test.txt', mode='w') as f:
f.writelines(l)
以下のようなファイルが生成されました。
リストの文字列に改行を含めることで1行ずつ書き込むことができる。
l = ['いち\n', 'に\n', 'さん']
with open('test.txt', mode='w') as f:
f.writelines(l)
print()関数で書き込む
print()
関数を使うことでもファイルに書き込むことができます。
print()
関数のfile
引数に任意のファイルオブジェクトを指定することで出力先を変更することができます。
with open('test.txt', 'w') as f:
print('print関数による書き込み', file=f)
以下のようにファイルに書き込むことができました。
ファイルの排他的な生成 'x'
open()
関数のモードに'x'
を指定することでパスで指定したファイルを生成することができます。すでに同じパスのファイルが存在する場合はエラーとなります。
このモードでは新たにファイルを生成する場合に上書きの危険性を回避することができます。ちなみに、生成されたファイルオブジェクトは書き込み用です。
with open('x.txt', 'x') as f:
f.write('排他的な生成')
以下のようにファイルが生成されました。
もう一度同じコードを実行するとFileExistsError
が送出されます。
書き込み、または追記 'a'
open()
関数のモードに'a'
を指定することで書き込み用としてファイルを開くことができます。すでに同じパスのファイルが存在していれば、そのファイルの末尾にどんどん追記していきます。
試しに同じファイルを何度も呼び出し書き込んでみます。
strings = []
# 3回文字列を入力してもらう
for i in range(3):
strings.append(input('文字を入力してください: '))
for string in strings:
# 同じファイルに書き込み
with open('strings.txt', 'a') as f:
f.write(string + '\n')
実行
文字を入力してください: one
文字を入力してください: two
文字を入力してください: three
以下のようなファイルが生成されました。
バイナリーモードで開く 'b'
バイナリファイルを扱いたい場合にはバイナリーモードでファイルを開く必要があります。mode
にb
を付けることでバイナリーモードとして実行することができます。
s = 'わ'
# 'わ'をbytesに変換
b = s.encode()
# 書き込み(rb = 書き込み + バイナリーモード)
with open('binary.bin', 'wb') as f:
f.write(b)
# 読み込み(rb = 読み込み + バイナリーモード)
with open('binary.bin', 'rb') as f:
b = f.read()
print(b)
# bytesからstrに変換
print(b.decode())
実行結果
b'\xe3\x82\x8f'
わ
ディレクトリ内に以下のようなバイナリーファイルが生成できました。
テキストモードで開く 't'
バイナリモードを指定していなければデフォルトでテキストモードでファイルを開いています。なので、いつもは省略されているだけで'w'
と'wt'
は等価です。
s = '書き込み'
with open('test.txt', 'wt') as f:
f.write(s)
with open('test.txt', 'rt') as f:
d = f.read()
print(d)
実行結果
書き込み
更新用で開く '+'
+
は、'r'
、または'rb'
と組み合わせることでファイル内の任意の箇所の文字のみを書き換えることができます。
例えば以下のようなテキストファイルがあったとします。
test.txt
abcd
123
あいう
このファイルを'r+'
で書き換えてみます。
s = 'zyx'
with open('test.txt', 'r+') as f:
f.write(s)
with open('test.txt', 'r') as f:
d = f.read()
print(d)
実行結果
zyxd
123
あいう
abc
の部分のみを書き換えることができました。
位置の移動[seekメソッド]
ファイルオブジェクトのseek
メソッドを使うことで書き込む位置を移動することができます。ただし、文字単位の移動なので扱いが難しいです。
s = 'zyx'
with open('test.txt', 'r+') as f:
f.seek(5)
f.write(s)
with open('test.txt', 'r') as f:
d = f.read()
print(d)
実行結果
zyxd
zyx
あいう
seek
メソッドで5文字目に移動したので5文字目から書き換えられました。
まとめ
この記事では、Pythonでファイルを読み書きする方法を解説しました。
ファイルを読み書きすることでセーブデータや設定ファイルなどを作ることができます。しかし、そのままファイルに書き込んでしまうと簡単に書き換えられてしまうので、暗号化などの一手間を加える必要があります。
また、設定の値を外部に保存する手段として設定ファイルを扱ったりします。
複数のファイルをまとめて読み込みたい場合は、fileinput を使うと便利です。
それでは今回の内容はここまでです!ではまたどこかで〜( ・∀・)ノ