ファイルシステム & OS環境マスター: pathlib vs os

シリーズ 02 – Pythonでフォルダとファイルを自在に扱う

プログラムを作るとき、ファイルを作成したり、フォルダを移動したり、パスを確認したりする作業は必須です。Pythonにはこの場面で「正解」が2つあります。 パスを優雅に扱う pathlib と、Pythonプログラムが実行される オペレーティングシステム(OS)環境自体を制御する os です。

機械とデジタルの出会い

pathlibがパス操作のスターなら、osは舞台裏で照明・音響・入口まで管理する 現場総括に近いです。1つを捨てるより、役割に合わせて併用する方が最もきれいです。


1. osとpathlib、何が違うのか?

Python 3.4から pathlib が導入され、パス処理の方法が大きく改善されました。

  • os / os.path
  • パスを基本的に 文字列 で扱います。
  • 関数型スタイルで、組み合わせが長くなると os.path.join()basename()splitext() など呼び出しが増えます。
  • それに対し「パス」だけでなく OS機能(環境変数、プロセス、権限など) も扱います。

  • pathlib

  • パスを オブジェクト(Path) で扱います。
  • / 演算子の組み合わせやメソッドチェーンのおかげでコードが短く直感的です。
  • ファイル/ディレクトリ探索、拡張子処理など「パス作業」は確実に pathlib が便利です。

2. 必要な作業別コード比較

2.1 現在の作業ディレクトリ確認とフォルダ作成

import os
from pathlib import Path

# os方式
current_os = os.getcwd()
if not os.path.exists("test_os"):
    os.makedirs("test_os")

# pathlib方式
current_pl = Path.cwd()
Path("test_pl").mkdir(exist_ok=True)

ヒント: 「パス」が目立つコードなら pathlib の方が保守性が高いです。


2.2 パス結合(差が最も大きく感じられる部分)

import os
from pathlib import Path

# os方式
path_os = os.path.join("usr", "bin", "python")

# pathlib方式(スラッシュ演算子)
path_pl = Path("usr") / "bin" / "python"

パス結合が増えるほど pathlib の方が読みやすくなります。


3. pathlibを推奨する理由: 「パスオブジェクト」の力

pathlib のメリットは「結合」で終わりません。ファイル情報を取り出す瞬間に差がさらに大きくなります。

機能 os.path 方式 pathlib 方式
ファイル名抽出 os.path.basename(p) p.name
拡張子除外名 os.path.splitext(os.path.basename(p))[0] p.stem
拡張子確認 os.path.splitext(p)[1] p.suffix
親ディレクトリ os.path.dirname(p) p.parent

このような「細かいパス処理」が積み重なると、pathlib で統一するとチームコードが一目で整理されます。


4. 実践例: 特定拡張子ファイルのみをすべて検索

プロジェクトフォルダ内で .txt ファイルだけを探し、リストを作る作業を行います。

from pathlib import Path

base_path = Path.cwd()
txt_files = list(base_path.rglob("*.txt"))  # 下位フォルダを含む再帰探索

for file in txt_files:
    print(f"ファイル名: {file.name}, 絶対パス: {file.resolve()}")

rglob() だけで再帰探索が完了します。「ファイル検索」作業は pathlib が本当に強力です。


5. しかし os が本当に強い領域がある: 「オペレーティングシステム環境」制御

ここからがバランスの核心です。 pathlib はパスの専門家ですが、OS自体を触る作業は os の舞台です。

5.1 環境変数の読み書き(デプロイ・セキュリティ・設定の核心)

開発/運用環境が変わると、設定はファイルより 環境変数 に分離されるケースが多いです。

import os

# 読み取り
db_url = os.environ.get("DATABASE_URL", "sqlite:///local.db")

# 書き込み(現在プロセスにのみ適用されるケースが一般的)
os.environ["APP_ENV"] = "production"

例: APIキー、実行モード、ログレベル、機能フラグ(feature flag)は pathlib ではなく os の領域です。


5.2 プロセス/コマンド実行: 「OSに仕事をさせる」機能

外部コマンドを実行したりプロセスを扱う作業は結局 OS 機能です。 os は低レベルインターフェースを提供するため、実際には OS にコマンドを渡すことに特化した subprocess がより頻繁に使われます(ただし出発点は OS 制御という点は同じです)。

import os

# 簡易実行(戻り値は終了コード)
exit_code = os.system("echo hello")
print(exit_code)

また、より細かなプロセス制御(実行/置換/フォークなど)の性格の関数も os 側に存在します。 pathlib が扱う「パス」とは全く別の領域です。


5.3 権限、ユーザー、作業ディレクトリなど「環境自体」を扱う

  • 権限変更(Unix 系): os.chmod()
  • 作業ディレクトリ変更: os.chdir()
  • プロセス/ユーザー関連情報: os.getpid() など

このような機能は pathlib が代替できません。 pathlib ができないことを os がやる という領域です。


6. 結論: pathlib, os の役割分担をしよう

  • パス操作 / ファイル探索 / ファイル名処理pathlib の方が読みやすく保守性が高いです。
  • 環境変数 / プロセス / 権限 / OS 機能全般os が担当する固有領域です。

実際に最良のパターンはこれです。

  • 「パスは Path で最後まで持っていく」
  • 「OS と対話する瞬間には os を使う」

7. 要約

  • pathlib はファイルシステムを扱うコードの 可読性と安定性 を大幅に向上させます。
  • os はパスを超えて、Python プログラムが置かれた オペレーティングシステム環境自体を制御します。
  • 正解は「どちらか一方」ではなく pathlib + os の組み合わせです。

一行でまとめ: パス/ファイル作業は pathlib でスッキリ、OS 環境制御は os で確実に。


関連記事 :