Pythonでパス文字列からファイル名・フォルダ名・拡張子を取得、結合

Pythonでパス文字列からファイル名・フォルダ名・拡張子を取得したり、文字列を結合してパスを生成したりするには、標準ライブラリのos.pathモジュールを使います。

11.2. os.path — 共通のパス名操作 — Python 3.6.5 ドキュメント

ここでは以下の内容について説明します。

OSによるパスの区切り文字の違い ファイル名を取得: os.path.basename() フォルダ名を取得: os.path.dirname() ファイル名とフォルダ名のペアを取得: os.path.split() パス文字列がフォルダを示す場合 拡張子を取得: os.path.splitext() 拡張子を変更したパス文字列を作成 ピリオドなしの拡張子を取得 ファイル名とフォルダ名を結合してパス文字列を作成: os.path.join() 同じフォルダの別のファイルのパス文字列を作成 異なるOSのフォーマットを利用 WIndowsの場合の例 区切り文字バックスラッシュとraw文字列 ファイル名、フォルダ名、拡張子の取得例 ドライブ文字を取得・結合: os.path.splitdrive()以下のパス文字列を例とします。実行環境はMac。

import os

filepath = './dir/subdir/filename.ext'

Windowsの場合の例は最後に示す。 なお、ここで説明するのはパス文字列からファイル名・フォルダ名(ディレクトリ名)を取得(抽出)する方法。フォルダ内に存在するファイル名一覧・パス一覧などを取得したい場合は

また、Python3.4以降ではパスをオブジェクトとして操作できるpathlibモジュールを使って同様にファイル名やフォルダ名、拡張子などを抽出することもできます。慣れるとpathlibのほうが使いやすい。

OSによるパスの区切り文字の違い

パスの区切り文字はOSによって異なります。 UNIX(Macを含む)ではスラッシュ/、Windowsではバックスラッシュ\が使われる。 Pythonが動作しているOSにおける区切り文字はos.sepまたはos.path.sepで取得、確認できます。

print(os.sep)
# /

print(os.sep is os.path.sep)
# True

ファイル名を取得: os.path.basename()

パス文字列からファイル名を取得するにはos.path.basename()を使います。ファイル名部分の文字列が返されます。

basename = os.path.basename(filepath)

print(basename)
# filename.ext

print(type(basename))
# <class 'str'>

フォルダ名(ディレクトリ名)を取得: os.path.dirname()

パス文字列からフォルダ名(ディレクトリ名)を取得するにはos.path.dirname()を使います。フォルダ名部分の文字列が返されます。

dirname = os.path.dirname(filepath)

print(dirname)
# ./dir/subdir

print(type(dirname))
# <class 'str'>

ファイルの直上のフォルダ名のみを取得したい場合はos.path.basename()と組み合わせる。

subdirname = os.path.basename(os.path.dirname(filepath))

print(subdirname)
# subdir

ファイル名とフォルダ名のペアを取得: os.path.split()

ファイル名とフォルダ名(ディレクトリ名)を両方取得するにはos.path.split()を使います。 os.path.basename()で取得できるファイル名の文字列とos.path.dirname()で取得できるフォルダ名の文字列のタプルが返されます。

base_dir_pair = os.path.split(filepath)

print(base_dir_pair)
# ('./dir/subdir', 'filename.ext')

print(type(base_dir_pair))
# <class 'tuple'>

print(os.path.split(filepath)[0] == os.path.dirname(filepath))
print(os.path.split(filepath)[1] == os.path.basename(filepath))
# True
# True

タプルのアンパックを利用してそれぞれの変数に代入することができます。

dirname, basename = os.path.split(filepath)

print(dirname)
print(basename)
# ./dir/subdir
# filename.ext

パス文字列がフォルダ(ディレクトリ)を示す場合

パス文字列がフォルダを示す場合、末尾に区切り文字があるかないかで結果が異なるので気をつけてください。 末尾に区切り文字がない場合です。

dirpath_without_sep = '../dir/subdir'

print(os.path.split(dirpath_without_sep))
# ('../dir', 'subdir')

print(os.path.basename(dirpath_without_sep))
# subdir

末尾に区切り文字がある場合です。最下層のフォルダ名を取得するには、os.path.dirname()とos.path.basename()を組み合わせる。

dirpath_with_sep = '../dir/subdir/'

print(os.path.split(dirpath_with_sep))
# ('../dir/subdir', '')

print(os.path.basename(os.path.dirname(dirpath_with_sep)))
# subdir

拡張子を取得: os.path.splitext()

拡張子を取得するにはos.path.splitext()を使います。 拡張子とそれ以外に分割されてタプルとして返されます。拡張子はピリオド.込みの文字列。

root_ext_pair = os.path.splitext(filepath)

print(root_ext_pair)
# ('./dir/subdir/filename', '.ext')

print(type(root_ext_pair))
# <class 'tuple'>

+演算子で結合すると元のパス文字列に戻る。

root, ext = os.path.splitext(filepath)

path = root + ext

print(path)
# ./dir/subdir/filename.ext

拡張子を変更したパス文字列を作成

元のパス文字列から拡張子だけを変更したパス文字列を作成するには、os.path.splitext()で取得できるタプルの1つ目の要素と任意の拡張子の文字列を結合します。

other_ext_filepath = os.path.splitext(filepath)[0] + '.jpg'

print(other_ext_filepath)
# ./dir/subdir/filename.jpg

ピリオドなしの拡張子を取得

ピリオドなしの拡張子を取得したい場合はスライス[1:]で2文字目以降を指定すれば問題ありません。

ext_without_period = os.path.splitext(filepath)[1][1:]

print(ext_without_period)
# ext

ファイル名とフォルダ名を結合してパス文字列を作成: os.path.join()

ファイル名とフォルダ名を結合して新たなパス文字列を作成するにはos.path.join()を使います。 引数に指定した文字列が区切り文字で区切られて結合されます。複数の文字列を指定できます。

path = os.path.join('dir', 'subdir', 'filename.ext')
print(path)
# dir/subdir/filename.ext

同じフォルダの別のファイルのパス文字列を作成

あるファイルと同一フォルダの別のファイルのパス文字列を作成したい場合は、os.path.dirname()とos.path.join()を組み合わせる。

other_filepath = os.path.join(os.path.dirname(filepath), 'other_file.ext')

print(other_filepath)
# ./dir/subdir/other_file.ext

異なるOSのフォーマットを利用

現在Pythonが動作しているOSではないOSのフォーマットでパス文字列を操作する場合は、osモジュールではなくそれぞれ別のモジュールをインポートして使います。

UNIX (現行のMac含む): posixpath Windows: ntpath Macintosh 9以前のMac: macpath

いずれのモジュールもos.pathと同一のインターフェイスを持っているため、これまでのサンプルコードのos.pathの部分をそれぞれのモジュール名(ntpathなど)に変更すれば動作します。

WIndowsの場合の例

WIndowsの場合の例を示す。 ここでは上述のntpathモジュールを使ってMac上で実行しています。 Windowsで実行する場合は以下のサンプルコード中のntpathをos.pathに置き換えても同様の結果となります。

区切り文字バックスラッシュとraw文字列

Windowsのパスの区切り文字はバックスラッシュ\。 コード中の文字列でバックスラッシュを記述するにはエスケープする必要があるため、バックスラッシュを2文字連続して書きます。print()ではバックスラッシュ1文字が出力されます。

import ntpath

print(ntpath.sep)
# \

print('\\')
# \

print(ntpath.sep is '\\')
# True

raw文字列(r'xxx')を使うとエスケープが無効になるのでWindowsで深い階層のパスを記述するのが楽。raw文字列と通常の文字列は書き方が違うだけで値としては等価。どちらを使ってもよい。

file_path = 'c:\\dir\\subdir\\filename.ext'
file_path_raw = r'c:\dir\subdir\filename.ext'

print(file_path == file_path_raw)
# True

raw文字列についてはバックスラッシュ1文字をraw文字列で表すことはできないので気をつけてください。

ファイル名、フォルダ名、拡張子の取得例

Windowsでも変わらず動作します。

print(ntpath.basename(file_path))
# filename.ext

print(ntpath.dirname(file_path))
# c:\dir\subdir

print(ntpath.split(file_path))
# ('c:\\dir\\subdir', 'filename.ext')

ドライブ文字を取得・結合: os.path.splitdrive()

ドライブ文字を取得するにはos.path.splitdrive()を使います。サンプルコードではntpath.splitdrive()になっています。 コロン:込みのドライブ文字とそれ以外に分割しタプルを返します。

print(ntpath.splitdrive(file_path))
# ('c:', '\\dir\\subdir\\filename.ext')

ドライブ文字のみ取得したい場合は1文字目を選択します。

drive_letter = ntpath.splitdrive(file_path)[0][0]

print(drive_letter)
# c

ドライブ文字を結合するには注意が必要。 os.path.join()にそのまま渡すと上手くいかない。

print(ntpath.join('c:', 'dir', 'subdir', 'filename.ext'))
# c:dir\subdir\filename.ext

区切り文字os.sep(サンプルコードではntpath.sep)も合わせてos.path.join()の引数として指定するか、ドライブ文字に区切り文字を加えてしまえば問題ありません。

print(ntpath.join('c:', ntpath.sep, 'dir', 'subdir', 'filename.ext'))
# c:\dir\subdir\filename.ext

print(ntpath.join('c:\\', 'dir', 'subdir', 'filename.ext'))
# c:\dir\subdir\filename.ext
Last Updated: 6/26/2019, 10:34:03 PM