ファイル操作を行うプログラムでは、「画像ファイル(.jpg, .png)だけを処理したい」「テキストファイル(.txt)以外は除外したい」といったように、ファイルの拡張子に基づいて処理を分岐させたい場面が多々あります。
Pythonの標準ライブラリ os.path モジュールには、ファイルパスから拡張子部分を簡単に切り出すための関数 splitext() が用意されています。
この記事では、os.path.splitext() の基本的な使い方と、ドット(.)が複数あるファイル名や拡張子がないファイルなどの特殊なケースにおける挙動について解説します。
os.path.splitext() の基本
os.path.splitext() は、引数として渡されたパス文字列を、**「拡張子以外の部分(root)」と「拡張子(ext)」**の2つに分割してタプルで返します。
構文:
import os
root, ext = os.path.splitext(パス文字列)
重要なポイントは、取得される拡張子 ext にはドット(.)が含まれるという点です。
具体的な使用例
画像ファイルのパスから拡張子を取り出し、処理対象かどうかを判定する例です。
import os
# 対象のファイルパス
image_path = "uploads/photos/sunset.jpg"
# パスを分割
root_part, extension = os.path.splitext(image_path)
print(f"元のパス: {image_path}")
print(f"ルート部分: {root_part}")
print(f"拡張子部分: {extension}")
# 拡張子による判定(小文字に変換してから比較するのが一般的)
if extension.lower() == ".jpg":
print("JPEG画像を検出しました。")
実行結果:
元のパス: uploads/photos/sunset.jpg
ルート部分: uploads/photos/sunset
拡張子部分: .jpg
JPEG画像を検出しました。
ルート部分には「ドライブ文字、ディレクトリパス、ファイル名(拡張子なし)」が含まれ、拡張子部分には「最後のドットを含む拡張子」が入ります。
特殊なケースにおける挙動
ファイル名にドットが含まれていたり、そもそも拡張子がなかったりする場合の挙動を理解しておくことは、バグを防ぐために重要です。
1. ドットが複数あるファイル名 (archive.tar.gz など)
splitext() は、一番最後にあるドットを区切り文字として認識します。そのため、.tar.gz のような二重拡張子は、最後の .gz だけが拡張子として扱われます。
import os
# 二重拡張子のファイル
archive_path = "backup.tar.gz"
root, ext = os.path.splitext(archive_path)
print(f"ファイル: {archive_path}")
print(f"ルート: {root}")
print(f"拡張子: {ext}")
実行結果:
ファイル: backup.tar.gz
ルート: backup.tar
拡張子: .gz
2. 拡張子がないファイル (README など)
ドットが存在しない場合、拡張子部分は空文字列 '' になります。
text_file = "README"
root, ext = os.path.splitext(text_file)
print(f"拡張子: '{ext}'") # 空文字列
実行結果:
拡張子: ''
3. ドットで始まるファイル (.gitignore など)
LinuxやmacOSの設定ファイルによくある「ドットファイル」の場合、そのドットは拡張子の区切りではなくファイル名の一部とみなされ、拡張子は空文字列となります(先頭以外にドットがない場合)。
config_file = ".gitignore"
root, ext = os.path.splitext(config_file)
print(f"ルート: {root}")
print(f"拡張子: '{ext}'")
実行結果:
ルート: .gitignore
拡張子: ''
まとめ
os.path.splitext(path): パスを(root, ext)に分割します。- 拡張子
ext: ドット(.)を含みます(例:.jpg)。 - 判定時の注意:
if ext == "jpg":ではなくif ext == ".jpg":と記述する必要があります。 - 多重拡張子: 最後のドット以降のみが拡張子として扱われます。
ファイルの種別判定や、出力ファイル名の生成(拡張子だけ変えて保存するなど)において、この関数は非常に有用です。
