pathlib と os.path の違いと使い分け

Python でファイルパスを扱う方法として、従来の os.path モジュールと Python 3.4 で導入された pathlib モジュールがある。どちらも同じ処理ができるが、書き方や考え方が異なる。

基本的な違い

os.path は文字列を操作する関数群で、pathlib はパスをオブジェクトとして扱う。

import os
from pathlib import Path

# os.path(文字列操作)
path = '/home/user/data.txt'
dirname = os.path.dirname(path)
basename = os.path.basename(path)

# pathlib(オブジェクト指向)
path = Path('/home/user/data.txt')
dirname = path.parent
basename = path.name

パスの結合

パスを結合する方法が大きく異なる。

import os
from pathlib import Path

# os.path
full_path = os.path.join('/home', 'user', 'data.txt')

# pathlib(/ 演算子を使用)
full_path = Path('/home') / 'user' / 'data.txt'

pathlib/ 演算子は直感的で可読性が高い。

メソッドチェーン

pathlib ではメソッドチェーンで複数の操作を繋げられる。

from pathlib import Path

# 親ディレクトリの親の中にある config.json
config = Path(__file__).resolve().parent.parent / 'config.json'

os.path で同じことをすると冗長になる。

import os

config = os.path.join(
    os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
    'config.json'
)

ファイル操作

pathlibPath オブジェクトはファイル操作のメソッドも持っている。

from pathlib import Path

path = Path('data.txt')

# 読み書き
content = path.read_text()
path.write_text('new content')

# 存在確認
if path.exists():
    print('存在する')

# 削除
path.unlink()

os.path では別のモジュールと組み合わせる必要がある。

import os

path = 'data.txt'

# 読み書きには open() を使う
with open(path) as f:
    content = f.read()

# 存在確認
if os.path.exists(path):
    print('存在する')

# 削除には os.remove() を使う
os.remove(path)

どちらを使うべきか

新しいコードでは pathlib を使うのがおすすめだ。可読性が高く、パスとファイル操作を統一的に扱える。ただし、以下の場合は os.path が適している。

古いコードベースとの一貫性を保ちたい場合
文字列としてのパスを多用する外部ライブラリと連携する場合
Python 3.4 より前のバージョンをサポートする必要がある場合

pathlibPath オブジェクトは str() で文字列に変換できるため、文字列を要求する関数にも渡せる。Python 3.6 以降では、多くの標準ライブラリが Path オブジェクトを直接受け入れるようになっている。