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'
)
ファイル操作
pathlib の Path オブジェクトはファイル操作のメソッドも持っている。
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 より前のバージョンをサポートする必要がある場合
pathlib の Path オブジェクトは str() で文字列に変換できるため、文字列を要求する関数にも渡せる。Python 3.6 以降では、多くの標準ライブラリが Path オブジェクトを直接受け入れるようになっている。