os/pathの形式に関わらず、パスからファイル名を抽出します。

OSやパスの形式に関わらず、パスからファイル名を抽出するPythonライブラリを教えてください。

例えば、これらのパスのすべてが c を返すようにしたいとします。

a/b/c/
a/b/c
\a\b\c
\a\b\c\
a\b\c
a/b/../../a/b/c/
a/b/../../a/b/c
ソリューション

他の人が言うように os.path.splitos.path.basename を使っても、すべての場合にうまくいくわけではありません。たとえば、Linux でこのスクリプトを実行しているときに、古典的な Windows スタイルのパスを処理しようとすると、失敗します。

Windowsのパスは、パスの区切り文字としてバックスラッシュかフォワードスラッシュのどちらかを使用できます。ですから、ntpathモジュール(Windows上で実行されているときはos.pathと同等です)は、すべてのプラットフォーム上のすべての(1)パスに対して動作します。

import ntpath
ntpath.basename("a/b/c")

もちろん、ファイルの末尾がスラッシュであればベースネームは空になりますので、それを処理する関数を自作してください。

def path_leaf(path):
    head, tail = ntpath.split(path)
    return tail or ntpath.basename(head)

検証します。

>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c', 
...     'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [path_leaf(path) for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']


(1) 1つ注意点があります。Linuxのファイル名には、バックスラッシュ*が含まれることがあります。Linuxでは、r'a/b\c'は、aフォルダ内のb\cというファイルを指しますが、Windowsでは、aフォルダのbサブフォルダ内のcというファイルを指します。つまり、パスにフォワードスラッシュとバックスラッシュの両方が使われている場合、それを正しく解釈するためには、関連するプラットフォームを知っている必要があります。実際には、Linux のファイル名にバックスラッシュが使われることはほとんどないので、Windows のパスだと考えても安全ですが、誤ってセキュリティホールを作ってしまわないように、コードを書くときにはこのことを念頭に置いてください。

解説 (7)

os.path.split です。 は、お探しの関数です。

head, tail = os.path.split("/tmp/d/a.dat")

>>> print(tail)
a.dat
>>> print(head)
/tmp/d
解説 (3)
import os
head, tail = os.path.split(p)
print tail

p が入力文字列で、tail が欲しいものだとします。

詳細は python os module docs を参照してください。

解説 (1)