概要(pathlib の結合は「/ 演算子」で直感的に安全に書く)
pathlib はファイルパスをオブジェクトとして扱う標準ライブラリです。結合は os.path.join を忘れて「/ 演算子」か joinpath を使うのが基本。OS差異(区切り文字)を気にせず、読みやすく安全に書けます。重要なのは「結合のルール(絶対パスが来たら上書き)」「相対/絶対の扱い」「存在確認と作成の分離」を押さえることです。
基本の結合(ここが重要)
/ 演算子でつなぐ(最短で読みやすい)
from pathlib import Path
base = Path("data")
p = base / "logs" / "2025" / "access.log"
print(p) # data/logs/2025/access.log(OSに応じて自動調整)
Python「/」は path 結合としてオーバーロードされており、文字列連結より安全で明快です。左が Path なら右は文字列でも Path でもOKです。
joinpath でまとめて渡す(可変個引数)
base = Path("data")
p = base.joinpath("logs", "2025", "access.log")
Python多段結合を1行で渡したいときに便利です。/ と好みで使い分けて構いません。
Path(…) に複数パーツを渡す(基点から一気に作る)
p = Path("data", "logs", "2025", "access.log")
Python「最初の引数が絶対パスならそれが基点」になります。相対ならカレントからの相対パスです。
結合ルールの深掘り(上書き・正規化・相対と絶対)
途中で「絶対パス」を渡すとそこから上書きになる
base = Path("data")
p = base / "/var" / "tmp" # Linux/macOS例
print(p) # /var/tmp(絶対パスに切り替わる)
Pythonpathlib は「絶対パスが現れたら、前の部分を捨ててその絶対パスを基点」にします。意図しない上書きを防ぐには、ユーザー入力などを結合する前にチェックしましょう。
..(親ディレクトリ)や . の扱い(正規化は明示)
p = Path("data") / "logs" / ".." / "output.txt"
print(p) # data/logs/../output.txt(そのまま保持)
print(p.resolve())# 絶対+正規化(実在パス前提)
print(p.absolute()) # 絶対化(正規化はしない場合あり)
Python見た目を整えたいなら resolve(実在が前提)か、PurePath系のメソッドを使います。存在しないパスでも正規化したい場合は注意が必要です。
parent・name・stem・suffix で安全に操作
p = Path("data/logs/access.log")
print(p.parent) # data/logs
print(p.name) # access.log
print(p.stem) # access
print(p.suffix) # .log
Python結合だけでなく、分解や差し替えを組み合わせると安全なパス操作が書けます。
with_name / with_suffix で差し替え
p = Path("data/logs/access.log")
print(p.with_name("error.log")) # data/logs/error.log
print(p.with_suffix(".txt")) # data/logs/access.txt
Pythonよくある実務パターン(存在確認・作成・展開)
ディレクトリがなければ作る(parents=True, exist_ok=True)
p = Path("data/logs/2025/access.log")
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text("hello\n", encoding="utf-8")
Python結合→親ディレクトリ作成→書き込みの流れが定番。存在確認は exists() / is_file() / is_dir() を使います。
ホーム・カレントの扱い(~ と cwd)
home = Path("~").expanduser() # ユーザホーム
p = home / "Downloads" / "report.pdf"
cwd = Path.cwd() # カレントディレクトリ
tmp = cwd / "tmp" / "work"
Python~ は expanduser() で展開します。カレント基準で相対を作るなら Path.cwd() を積極的に使いましょう。
glob で結合先を走査(パターン検索)
base = Path("data/logs/2025")
for f in base.glob("*.log"):
print(f) # data/logs/2025/xxx.log
Python結合した基点からパターン検索。再帰なら rglob(“*/.log”) です。
open と read/write は Path から直接
p = Path("data/logs/access.log")
with p.open("a", encoding="utf-8") as fp:
fp.write("more\n")
txt = p.read_text(encoding="utf-8")
p.write_bytes(b"\x00\x01")
Python安全性と設計の勘所(入力の検証・型の一貫性・文字列化)
ユーザー入力と結合するときのガード
- 絶対パス/ルートの持ち込み(/ やドライブレター)で基点が上書きされます。許可するかを決め、必要なら拒否・正規化しましょう。
- 「..」での親参照(ディレクトリ・トラバーサル)も検証してから結合します。
def safe_join(base: Path, *parts: str) -> Path:
p = base.joinpath(*parts).resolve()
if base.resolve() not in p.parents and p != base.resolve():
raise ValueError("base外へのパスは禁止")
return p
PythonPath を最後まで維持して、必要時だけ str にする
p = Path("data") / "logs" / "access.log"
# ライブラリが文字列パスを要求するなら str(p)
some_api(str(p))
Python中間で文字列化すると OS非依存の利点やメソッド連鎖が失われます。最後のインタフェースだけ変換します。
f-string は表示用途に限定
print(f"Path: {p}") # OK(表示)
# 結合は f-string ではなく / を使う
Python文字列連結でパスを作らない。pathlib の演算子とメソッドを使う方が安全です。
例題で身につける(定番から一歩先まで)
例題1:ログファイルの今日分パスを作る
from pathlib import Path
from datetime import date
base = Path("logs")
today = date.today().strftime("%Y%m%d")
p = base / today / "app.log"
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text("start\n", encoding="utf-8")
print(p)
Python例題2:絶対パスの混入を防いで結合
from pathlib import Path
def join_strict(base: Path, *parts: str) -> Path:
for s in parts:
if Path(s).is_absolute():
raise ValueError(f"絶対パスは禁止: {s}")
return base.joinpath(*parts)
root = Path("/srv/app")
print(join_strict(root, "data", "files", "a.txt")) # /srv/app/data/files/a.txt
Python例題3:拡張子を差し替えて出力先作成
from pathlib import Path
src = Path("data/input/report.csv")
out = src.with_suffix(".parquet")
out.parent.mkdir(parents=True, exist_ok=True)
print(out) # data/input/report.parquet
Python例題4:ホーム配下に安全に保存(~ 展開)
from pathlib import Path
home = Path("~").expanduser()
save = home / "Documents" / "notes" / "memo.txt"
save.parent.mkdir(parents=True, exist_ok=True)
save.write_text("memo\n", encoding="utf-8")
Pythonまとめ
pathlib の結合は「/ 演算子」か joinpath を使うのが最短で安全。絶対パスが混ざると基点が上書きされるルール、resolve/absolute の違い、親ディレクトリ操作(parent)と分解(name/stem/suffix)、差し替え(with_*)まで押さえると迷いません。ディレクトリ作成は mkdir(parents=True, exist_ok=True) をセットで。Path を保ったまま操作し、最後だけ str へ変換する方針で、OS非依存・読みやすさ・安全性を同時に満たしましょう。

