note.nkmk.me

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

Date: 2018-04-16 / tags: Python, ファイル操作, 文字列操作

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

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

  • 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文字目以降を指定すればOK。

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で実行する場合は以下のサンプルコード中のntpathos.pathに置き換えても同様の結果となる。

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

Windowsのパスの区切り文字はバックスラッシュ\

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

import ntpath

print(ntpath.sep)
# \

print('\\')
# \

print(ntpath.sep is '\\')
# True
source: os_ntpath.py

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
source: os_ntpath.py

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')
source: os_ntpath.py

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

ドライブ文字を取得するにはos.path.splitdrive()を使う。サンプルコードではntpath.splitdrive()になっている。

コロン:込みのドライブ文字とそれ以外に分割しタプルを返す。

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

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

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

print(drive_letter)
# c
source: os_ntpath.py

ドライブ文字を結合するには注意が必要。

os.path.join()にそのまま渡すと上手くいかない。

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

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

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
source: os_ntpath.py
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事