os.path から pathlib への移行
一言まとめ
os.path の主要な操作を pathlib に置き換える対応表。結合は / 演算子、親は .parent、拡張子は .suffix。
| os.path など | pathlib |
|---|---|
os.path.join(a, b) | Path(a) / b |
os.path.dirname(p) | Path(p).parent |
os.path.basename(p) | Path(p).name |
os.path.splitext(p)[0] | Path(p).with_suffix("") |
os.path.splitext(p)[1] | Path(p).suffix |
os.path.abspath(p) | Path(p).resolve() |
os.path.exists(p) | Path(p).exists() |
os.makedirs(p, exist_ok=True) | Path(p).mkdir(parents=True, exist_ok=True) |
glob.glob("src/*.py") | Path("src").glob("*.py") |
open(p).read() | Path(p).read_text() |
要点は4つです。連結は / 演算子、階層は .parent、拡張子は .stem と .suffix、探索は .glob()。
.stem は splitext の代わりにはなりません。splitext("a/b/c.txt")[0] はディレクトリを残した "a/b/c" を返しますが、.stem はファイル名だけの "c" です。パスとして拡張子を落とすなら .with_suffix("") を使います。.resolve() も完全な abspath 相当ではなく、.. の正規化に加えてシンボリックリンクまで辿ります。リンクのまま残したいなら向きません。
from pathlib import Path
for md in Path("src/content/posts").glob("*/index.md"): print(md.parent.name, md.read_text().splitlines()[0]).parent は繋げられるので p.parent.parent で2階層上、p.parents[1] でも同じです。
文字列が必要になる場面は残ります。os.PathLike を受け取らない古いライブラリや、パスを含む文字列を組み立てるときは str(p) を挟みます。標準ライブラリと open() はそのまま Path を受け取れます。
関連
更新履歴
- 2026-06-25: 初版(memos から移行)
- 2026-10-09: 関連に ruff の最小構成を追加(PTH ルールで os.path を検出できる)
- 2026-10-09: タイトルを概念名に揃え、tags を補う