はじめに
- 今回はpythonで基本的なファイルの読み書き操作をやってみたいと思います。
- 以下の環境で動作確認をしています。
- python: Python 3.11.0
- os: macOS Ventura
ファイルの書き込み
open関数でファイルを開く
open関数の引数にファイルパスとwモードを指定して実行し、その後closeメソッドでファイルを閉じます。今回は相対パスでカレントディレクトリに存在しないファイル
を指定します。実行後、カレントディレクトリに該当ファイルが新規作成
されます。
f = open("sample.txt", "w")
f.write("test")
f.close()
test
という文字列が該当ファイルに書き込まれています。
test
with文でファイルを開く
openで開いたファイルを最後にcloseし忘れると
、ファイルを開いたまま
にしてしまい、その分のメモリを使ってしまいます。それを防ぐために、with文を使いましょう。
with open("sample.txt", "w") as f:
f.write("test")
上記のように書くと、インデントの中の処理が終了すると、closeを書かなくても
ファイルをcloseしてくれます。また、as f
のf
というのは、開いたファイルを入れる変数なので、他の名前をつけても構いません。
書き換えと追記
では、ファイルに書き込む文字列を変えて、再度実行してみます。
with open("sample.txt", "w") as f:
f.write("TEST")
ファイルを開いてみると、中身がTEST
に書き換えられていることがわかります。
※wモードでは、対象ファイルが存在する場合、ファイルの中身が新しい文字列で書き換えらます
。また、書き込みの処理がなくても、ファイルを開いた直後に中身が空になる
ので、操作ミスしないように気をつけましょう。
TEST
書き換えるのではなく、追記する場合
はaモードを使いましょう。
with open("sample.txt", "a") as f:
f.write("TEST")
TESTTEST
改行を入れる
改行コードで改行を入れてみます。
with open("sample.txt", "w") as f:
f.write("TEST\nTEST\n")
TEST
TEST
また、以下のように、複数行の文字列を書き込むこともできます。
fruits = """\
apple
banana
orange
"""
with open("sample.txt", "w") as f:
f.write(fruits)
apple
banana
orange
※CRLFの改行コード(主にWindows)の場合は二文字(\r\n)になるので、複数行の文字列を書き込む際に、newline="\n"
のようにopen関数のnewline引数を指定することで、改行コードがLF(\n)のテキストを作成できます。
writelinesメソッドでリストを書き込む
writelinesメソッドで、リスト
を書き込むことができます。
fruits = ["apple", "banana", "orange"]
with open("sample.txt", "w") as f:
f.writelines(fruits)
ただwritelinesメソッドは改行コードを入れてくれないので、リストの要素が連結されたまま
書き込まれます。
applebananaorange
リストの要素ごとに改行コードを追加せずに改行を入れたい場合は、以下のような方法があります。
fruits = ["apple", "banana", "orange"]
with open("sample.txt", "w") as f:
f.write("\n".join(fruits))
joinメソッドを使って、改行コードでリストの要素を連結した文字列を作成し、writeメソッドで書き込むという方法です。ただ最後の要素の後ろには改行コードが含まれない
ので、ご注意ください。
apple
banana
orange
ファイルが存在しない場合のみ新規作成して書き込む
ファイルが存在しない場合のみ新規作成し書き込みたい場合は、xモードを使いましょう。ファイルが存在する場合はエラーになります。
with open("new_sample.txt", "x") as f:
f.write("test")
実行後、new_sample.txtというファイルが新規作成され、testという文字列が書き込まれています。
test
すでに存在しているsample.txtをxモードで開いたら、以下のようにエラーが表示されることがわかるかと思います。
with open("sample.txt", "x") as f:
f.write("test")
FileExistsError: [Errno 17] File exists: 'sample.txt'
print関数で書き込む
ファイルに内容を書き込む際に、writeメソッドだけでなく、print関数も使えます。print関数の引数にfile=f
のように書けば書き込み先を指定できます。
with open("sample.txt", "w") as f:
print("test from print", end="", file=f)
test from print
print関数のさまざまな出力方法でそのままファイルに書き込めるという利点があります。ただwriteメソッドの方が、ファイルオブジェクトにメソッドで書き込むということがわかりやすいので、writeメソッドの方が一般的
かと思います。
ファイルの読み込み
readメソッドで全文を読み込む
次にファイルの読み込み操作をやってみたいと思います。sample.txtというファイルに以下の内容が書き込まれているとします。
apple
banana
orange
rモードでファイルを開いて、readメソッドでファイル全体
を読み込んでみます。
with open("sample.txt", "r") as f:
print(f.read())
ファイル全体を文字列として取得し、printで以下のように出力します。
apple
banana
orange
※引数モードのデフォルト値がrになっているので、rモードの場合モード引数の記述を省略することもできますが、記述してあげた方がわかりやすいかと思います。
readメソッドで文字数を指定して読み込む
readメソッドの引数に読み込みたい文字数を指定
し、ファイル内の現在位置から読み込む
ことができます。
with open("sample.txt", "r") as f:
print(f.read(1))
現在位置は先頭から始まるので、先頭から1文字だけ読み込むことになります。(appleのa)
a
tellメソッドで現在位置を取得
tellメソッドで、ファイル内の現在位置を取得
することができます。
with open("sample.txt", "r") as f:
# ファイルの先頭から移動していないので、0が返される
print(f.tell()) # 0
# 先頭から一文字を読み込む
print(f.read(1)) # a
# 一文字分読み込まれたので、現在位置が1になる
print(f.tell()) # 1
# もう一度一文字を読み込むと、二文字目のpが読み込まれる
print(f.read(1)) # p
0
a
1
p
seekメソッドでファイル内の特定の場所に移動
seekメソッドでファイル内の特定の場所に移動
することができます。
with open("sample.txt", "r") as f:
f.seek(6)
print(f.read(1))
ファイルの先頭0から数えて6番目の文字が表示されます。改行(\n)も一文字とカウント
されるので、二行目の最初の文字が表示されます。(bananaのb)
b
readlineメソッドで一行ずつ読み込む
readlineメソッドでファイルの先頭から一行ずつ
読み込むことができます。
with open("sample.txt", "r") as f:
while True:
# ファイルの先頭から一行ずつ読み込む
line = f.readline()
print(line)
# 読み込む行がなくなったらループを抜ける
if not line:
break
ただreadlineメソッドでは、最終行(4行目)の空行(EOF)は空文字列として返されます。
apple
banana
orange
また、ファイルオブジェクトをfor文で回しても、先頭から一行ずつ取得できます。
with open("sample.txt", "r") as f:
for line in f:
print(line)
apple
banana
orange
※上記いずれの場合も改行コードを含む行を取得できます。
readlinesメソッドでファイル全体をリストとして読み込む
readlinesメソッドでファイル全体を行ごとに分割したリスト
として取得できます。リストの各要素に改行コードが含まれます
。
with open("sample.txt", "r") as f:
lines = f.readlines()
print(lines)
['apple\n', 'banana\n', 'orange\n']
改行コードを取り除く
readlineメソッドで取得した文字列
まずreadlineメソッドで取得した文字列に含まれる改行コードを取り除いてみます。以下の2つの方法があります。
with open("sample.txt", "r") as f:
# 改行コードを空文字列に置換
line = f.readline().replace("\n", "")
print(line)
apple
with open("sample.txt", "r") as f:
# 文字列の末尾の改行文字を取り除く
line = f.readline().rstrip("\n")
print(line)
apple
readlinesメソッドで取得したリスト
readlinesメソッドで取得したリストに含まれる改行コードを取り除いてみます。以下の2つの方法があります。
with open("sample.txt", "r") as f:
lines = f.readlines()
# リストの内包表記でrstripで各要素の改行コードを取り除く
lines_rstrip = [line.rstrip("\n") for line in lines]
print(lines_rstrip)
['apple', 'banana', 'orange']
with open("sample.txt", "r") as f:
# 改行コードを含むファイル全体を文字列として取得し、
# splitlinesで改行コードで分割されたリストを取得
lines = f.read().splitlines()
print(lines)
['apple', 'banana', 'orange']
読み込みと書き込みを同時に行う
wモードで内容を書き込んでから、readメソッドなどで読み込むと、io.UnsupportedOperation: not readable
というエラーになります。
読み込むためにrモードでファイルを開き直したくない場合は、以下の2つの方法があります。
w+モード
w+モードは、wモードと同じように対象ファイルが存在しない場合は新規作成します。
また書き込んだ直後、ファイル内の現在位置が最後になってしまうので、f.seek(0)
でファイルの先頭に移動する必要があります。
with open("sample.txt", "w+") as f:
f.write("test")
f.seek(0)
print(f.read())
test
※w+モードでは、wモードと同じように、ファイルを開いた直後にファイルの中身が空になるので、書き込みをせずにいきなり読み込もうとしても、何も読み込まれません。
r+モード
r+モードは既存ファイルの読み書き用モードです。そのため、存在しないファイルを開こうとしたらエラーになるので、ご注意ください。
モードの一覧
モード | 説明 | 補足 |
---|---|---|
t | テキストモード | デフォルト、r, w, aと一緒に指定する |
r | 既存ファイルの読み込み | デフォルト |
w | 書き込み | ファイルが存在する場合は書き換え(ファイルを開いた直後に中身が空になる)、存在しない場合は新規作成 |
a | 追記 | ファイルが存在する場合は末尾に追記、存在しない場合は新規作成 |
b | バイナリモード | バイナリファイル用、r, w, aと一緒に指定する |
x | 排他的書き込み | ファイルが存在しない場合は新規作成、存在する場合はエラーになる |
+ | 更新用(読み書き) | r, w, a, xと一緒に指定する |