Python Tech 文字列

Python 文字列をファイルに保存(書き込み)する方法

Pythonの文字列は簡単にファイルに保存(書き込み)することができます。

標準の組み込み関数 open() でファイルを開き(作成)、変数の中身を write() などで書き込むだけです。とはいえ状況に応じて使い方を変える必要があり、後で迷ったときに見返せるよう整理しています。

  • ファイルを新規作成する
  • 既存ファイルがあって、上書きする
  • 既存ファイルがないときだけ新規作成して書き込む(あるときは何もしない)
  • 既存ファイルの末尾に追記する
  • 既存ファイルの先頭に挿入する

このようなPythonコードの書き方について、現役のエンジニアが解説しています。

 

結論

上書きor新規作成モードでファイルを開き、文字列を書き込み(mode='w')

with open('./test/data/file_open.txt', 'w') as f:
    f.write("new contents")

 

新規作成専用モードでファイルを開き、文字列を書き込み(mode='x')
(別途エラーハンドリングは必要)

with open('./test/data/file_open_new.txt', 'x') as f:
    f.write("new file!")

 

既存ファイルへの追記モードで書き込み(mode='a')
ファイルの末尾に追記される。

with open('./test/data/file_open.txt', 'a') as f:
    f.write("\nadditional contents")

 

実行環境

Python 3.9.2
Debian GNU/Linux 10 (buster)

 

open() 読み書きモードのまとめ

f = open(file, mode)

r(デフォルト)読み出し専用
w書き込み専用(新規作成or上書きモード)
x書き込み専用(新規作成専用モード)
a書き込み専用(末尾へ追記モード)
r+読み書き両用

 

上書きor新規作成モードでファイルに書き込み

Pythonでファイルを開くには組み込み関数の open() を使います。

open()の引数構造は次の通り。書き込みモードにするには第2引数modeを"w", "x", "a"のいずれかに指定します。

file = open(file, mode)

fileファイルパス。絶対パスでも相対パスでもOK
mode読み書きモード。上記表を参照

 

以下は open() をそのまま使ってファイルを開き、文字列を書き込むサンプル。
write() に渡した内容でファイルへ書き込みます。

f = open('./test/data/file_open.txt', 'w')
f.write("new contents")
f.close()

f = open('./test/data/file_open.txt', 'r')
print(f.read())
f.close()
# new contents

 

モード "w" は、ファイルが存在しない場合は新規作成し、既に存在する場合は上書き(内容を完全に消去してから新たに書き込み)します。

ファイルをオープンしたら、最後に close() でファイルをクローズする必要があります。クローズを忘れると、ファイルが正しく書き込まれない、次回にファイルを開けないといった可能性があります。

with ブロック文を使えば、ブロックを抜けるときにclose() を自動で呼ぶのでclose() の記述が不要になります。

with open('./test/data/file_open.txt', 'w') as f:
    f.write("new contents")

 

直上のディレクトリが存在しないとき(ファイルを作成できないとき)はFileNotFoundError例外になります。

with open('./non-exist-dir/file.txt', 'w') as f:
     f.write("new contents")
# FileNotFoundError: [Errno 2] No such file or directory: './non-exist-dir/file.txt'

 

ディレクトリも自動で作成するには、os.path.exists() などで存在を事前に判定、os.makedirs で作成しておきます。

import os
work_dir = './non-existent-dir'
if not os.path.isdir(work_dir):
    os.makedirs(work_dir)

with open(f'{work_dir}/file.txt', 'w') as f:
    f.write("new file")

 

新規作成のみのモードでファイルに書き込み

open() のモードを "x"とすると、新規作成のみを許可するモードでファイルに書き込みます。

with open('./test/data/file_open_new.txt', 'x') as f:
    f.write("New file!")
    
with open('./test/data/file_open_new.txt', 'r') as f:
    print(f.read())
# New file!

 

すでにファイルが存在する場合はFileExistsErrorがraiseされます。

# FileExistsError: [Errno 17] File exists: './test/data/file_open_new.txt'

 

既にファイルが存在するときはパス(何もしない)

ファイルが無いときのみ新規作成(書き込み)するにはどうしたらいいでしょうか?

モードを "x" とするとき、ファイルが無ければ新規作成し、存在すれば例外 FileExistsError がraiseされます。

存在するときにパスする(何も処理しない)には try-catch文で例外処理を書きます。
サンプルではprint()で表示するだけで、ファイルには一切操作をしません。

try:
    with open('./test/data/file_open_new.txt', 'x') as f:
        f.write("New file!")
except FileExistsError:
    print("ファイルは既に存在します")
# ファイルは既に存在します

 

ファイルの存在を事前にチェックする方法でも同じことが実現できます。
os.path.isfile() などでファイルの存在を確認できます。

import os
fp = './test/data/file_open_new.txt'
print(os.path.isfile(fp))
# True

if not os.path.isfile(fp):
    with open('./test/data/file_open_new.txt', 'x') as f:
        f.write("This is the newly created file!")

 

既存ファイルへの追記モードで書き込み

すでに存在するファイルに文字列を書き加えるにはモード mode"a"とします。

with open('./test/data/file_open.txt', 'r') as f:
    print(f.read())
# new contents

with open('./test/data/file_open.txt', 'a') as f:
    f.write("\nadditional contents")

with open('./test/data/file_open.txt', 'r') as f:
    print(f.read())
# new contents
# additional Contents

 

モード "a" では、既存のファイル内容はそのままで、末尾にテキストを追加(追記)します。追記する位置を選ぶことはできません。

 

先頭に追加(挿入)する場合

open(), write() ではファイルの任意の位置に文字列を書き込む機能はありません。

ファイルの先頭(1行目~)にテキストを挿入するには、一度元のファイルの内容を読み取り、先頭部分を書き込んだあとに、再度元のファイル内容を書き込みます。

f.readlines() はファイルの各行をリスト(list)として読み込みます。

# 元のファイル内容を読み込み
with open('./test/data/file_open.txt', 'r') as f:
    old_texts = f.readlines()
print(old_texts)
# ['new contents\n', 'additional contents']

# 先頭部分を書き込み
with open('./test/data/file_open.txt', 'w') as f:
    f.write("new top line\n")

# 元のファイル内容を書き込み(追加)
with open('./test/data/file_open.txt', 'a') as f:
    f.writelines(old_texts)

# 結果の表示
with open('./test/data/file_open.txt', 'r') as f:
    print(f.read())
# new top line
# new contents
# additional contents

 

また、ファイルの中間の任意の位置に挿入する場合も、元の内容をf.readlines()で取得し、任意の位置に挿入して書き込みすればOKです。

 

今回参考にしたページ・資料

7.2. ファイルを読み書きする 7. 入力と出力 — Python 3.9.4 ドキュメント

  • この記事を書いた人

次世代ペンギン

長いのでペンギンとお呼びください。システム開発・プログラミングのお仕事をしています。甘味とコーヒーは生命線。多くの人に役立つ情報のシェアが目標です。

人気の記事

1

会社員でプログラマーとして働いている人、インフラやネットワークのエンジニアとして働いている人の中には、フリーランスのプログラマーとして独立、もしくは転向したい人もいるので ...

2

キャリアアップのため、または高収入を目指して、しっかりプログラミングを学びたいという人が増えてきましたね。 この記事では現役のエンジニアである私が、実際に仕事で稼げるよう ...

3

フリーランスのプログラマーにとって収入の向上に最も直結するのはスキルです。 必要なスキル、スキルの獲得方法が気になる人も多いでしょう。 また、これからフリーランスを目指す ...

4

Vuetifyの v-progress-circular コンポーネントは、数値データや処理状況を環状(円状)のデザインで教えてくれるUIデザインです。 ローディングのス ...

5

Vuexのstore(ストア)を使うと、各コンポーネント間で個別にデータのやり取りすることなく、データを一元的に管理できます。Vueでは欠かせない機能といえるでしょう。 ...

-Python, Tech, 文字列
-, ,

© 2021 ペンギンのーと