ファイルシステムとOS環境を極める: pathlib vs os

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

プログラムを作るとき、ファイルを作成したり、フォルダを移動したり、パスを確認したりする作業は必須です。Pythonにはこの目的を達成するための主要な方法が2つあります。 パスをスマートに扱うpathlibと、Pythonプログラムが動作するオペレーティングシステム(OS)環境自体を制御するosです。

機械とデジタルの出会い

pathlibがパス操作の主役だとすれば、osは舞台裏で照明・音響・入口管理までを担う現場の総括責任者に近い存在です。どちらか一方を排除するのではなく、役割に応じて両者を併用するのが最も効果的です。


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プログラムが動作するオペレーティングシステム環境自体を制御します。
  • 最適な方法は「どちらか一方」ではなく、pathlibosの組み合わせです。

一行でまとめ: パス/ファイル作業はpathlibでスマートに、OS環境制御はosで確実に行いましょう。


関連記事 :