Python

ファイルとJSON

データをプログラムの終了後にも残し、安全に読み書きする方法を学びます。

01

パスを正しく扱う

ファイルの場所を表す文字列がパスです。pathlib.Path を使うと、OSによる区切り文字の違いを意識せずパスを組み立てられます。

スクリプトと同じ場所を基準にするPYTHON
from pathlib import Path

base_dir = Path(__file__).resolve().parent
data_dir = base_dir / "data"
file_path = data_dir / "message.txt"

data_dir.mkdir(exist_ok=True)
print(file_path)
ポイント Path.cwd() はコマンドを実行した場所、Path(__file__).parent はPythonファイルの場所です。目的に応じて区別します。
02

テキストを読み書きする

少量のテキストなら write_text()read_text() が簡単です。日本語の文字化けを防ぐため encoding="utf-8" を明示します。

書き込みと読み込みPYTHON
from pathlib import Path

path = Path("memo.txt")
path.write_text("1行目\n2行目\n", encoding="utf-8")

text = path.read_text(encoding="utf-8")
print(text, end="")
実行結果OUTPUT
1行目
2行目

追記や大きなファイルの一行処理には open() を使います。with の範囲を抜けると自動で閉じられます。

追記するPYTHON
with open("app.log", "a", encoding="utf-8") as file:
    file.write("プログラムを開始しました\n")
03

CSVを扱う

値にカンマや改行が含まれる可能性があるため、split(",") ではなく標準の csv モジュールを使います。

CSVを書いて読むPYTHON
import csv

rows = [["name", "score"], ["Aki", 82], ["Mika", 91]]

with open("scores.csv", "w", encoding="utf-8", newline="") as file:
    writer = csv.writer(file)
    writer.writerows(rows)

with open("scores.csv", encoding="utf-8", newline="") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(f"{row['name']}: {row['score']}点")
実行結果OUTPUT
Aki: 82点
Mika: 91点
Windowsでの空行対策 CSVを開くときは newline="" を指定します。
04

JSONを扱う

JSONは辞書やリストに近い形で構造を保存できます。ensure_ascii=False にすると日本語をそのまま保存できます。

JSONを保存して復元PYTHON
import json
from pathlib import Path

user = {"name": "Mity", "skills": ["Python", "PHP"]}
path = Path("user.json")

path.write_text(
    json.dumps(user, ensure_ascii=False, indent=2),
    encoding="utf-8",
)

loaded = json.loads(path.read_text(encoding="utf-8"))
print(loaded["skills"][0])
実行結果OUTPUT
Python
05

失敗と安全性を考える

確認すること
  • 読み込み前にファイルが存在するか確認する
  • PermissionError や文字コードの違いを想定する
  • 利用者の入力をそのままファイル名にしない
  • 重要なファイルをいきなり上書きしない
  • パスワードや秘密鍵を公開フォルダーへ保存しない
存在を確認するPYTHON
from pathlib import Path

path = Path("settings.json")

if path.exists():
    print(path.read_text(encoding="utf-8"))
else:
    print("設定ファイルがありません")
PRACTICE

ミニ課題:買い物メモ

商品名と個数を辞書のリストとしてJSONへ保存し、次の実行時に読み込んで一覧表示してください。

条件 ファイルがない初回は空のリストから始めること、日本語をそのまま保存すること、元ファイルを上書きする前にデータの形を確認することを意識してください。