採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

L?? ch01 — pathlib 基礎

テクノロジ系 / L09 file-io — ファイル永続化

L?? ch01 — pathlib 基礎

ファイルパスを「文字列連結」から卒業する

ゴール

  • pathlib.Path でファイルパスを表現できる
  • / 演算子でパスを連結できる
  • read_text() / write_text() で読み書きできる
  • exists() / is_file() / is_dir() で存在確認できる

なぜ pathlib か

# ❌ 文字列連結 (古い書き方)
import os
path = "data" + os.sep + "users" + os.sep + "taro.txt"

# ✅ pathlib (Python 3.4+ 標準)
from pathlib import Path
path = Path("data") / "users" / "taro.txt"
  • OS 差 (Windows \ / Unix /) を吸収
  • パス操作メソッドが豊富
  • 型として扱える (Path オブジェクト)

最小例

from pathlib import Path

p = Path("hello.txt")
p.write_text("Hello, pathlib")     # 書き込み
print(p.read_text())               # 読み込み → Hello, pathlib
print(p.exists())                  # True
uv run python main.py

パスを組み立てる

from pathlib import Path

base = Path("data")
user_file = base / "users" / "taro.txt"
# → data/users/taro.txt

# 親ディレクトリ
print(user_file.parent)       # data/users

# ファイル名
print(user_file.name)         # taro.txt

# 拡張子
print(user_file.suffix)       # .txt

# 拡張子を除いた名前
print(user_file.stem)         # taro

読み書き API

from pathlib import Path

p = Path("note.txt")

# 書き込み (上書き)
p.write_text("一行目\n二行目\n", encoding="utf-8")

# 読み込み (全体)
content = p.read_text(encoding="utf-8")

# バイナリ
p.write_bytes(b"\x00\x01\x02")
data = p.read_bytes()

存在確認 / ディレクトリ作成

from pathlib import Path

p = Path("data/output")

# 存在チェック
p.exists()        # True / False
p.is_file()       # ファイルか
p.is_dir()        # ディレクトリか

# ディレクトリを作る (親も含めて)
p.mkdir(parents=True, exist_ok=True)

parents=True: 中間ディレクトリも作る

exist_ok=True: 既にあってもエラーにしない

ディレクトリを走査

from pathlib name Path

base = Path("data")

# 直下のファイル/ディレクトリ
for child in base.iterdir():
    print(child)

# パターン一致 (* は任意の文字列)
for txt in base.glob("*.txt"):
    print(txt)

# 再帰的に検索 (**)
for py in base.rglob("*.py"):
    print(py)

__file__ と組み合わせる

スクリプト自身の場所を起点にしたいとき:

from pathlib import Path

# このスクリプトのパス
HERE = Path(__file__).resolve().parent

# 同じディレクトリの data.txt を読む
data = (HERE / "data.txt").read_text()

__file__ を直接文字列で扱わず Path で包むのがコツ。

よくある間違い

# ❌ Path を文字列の代わりに渡し忘れる
open("data/" + filename)         # OS 差で死ぬ

# ❌ exists() の戻り値を文字列と比較
if path.exists() == "True":      # bool なので == True いらない

# ❌ mkdir で exist_ok を忘れる
Path("data").mkdir()             # 2 回目で FileExistsError
Path("data").mkdir(exist_ok=True)   # ✅

drill

drill/ — パスを組み立てて読み書きする関数を完成させる

拡張課題

  1. 絶対パス化: Path("./foo").resolve() で絶対パスに変換
  2. 拡張子の差し替え: p.with_suffix(".bak")hello.txthello.bak
  3. glob で集計: あるディレクトリ配下の .log ファイルサイズ合計を出す
   total = sum(p.stat().st_size for p in Path("logs").glob("*.log"))
   

よくある詰まり

症状原因対処
FileNotFoundError相対パスの起点が想定と違うPath(__file__).parent を基準に
文字化けencoding 未指定read_text(encoding="utf-8")
mkdirFileExistsError既に存在するexist_ok=True
Windows でパス区切りが \OS 差pathlib なら自動吸収される

次に学ぶ領域

領域続けて読む
JSON 読み書きch02-json (= 次の chapter)
with 文 / opench03-open-with
CSV / Excel後続 lesson
力試ししたい方は クイズ形式の演習(任意) もあります。読むだけでも十分です。