Pythonのpathlibモジュールを使うと、ファイル・ディレクトリ(フォルダ)のパスをオブジェクトとして操作することができ、os.pathより簡単にパスを扱えます。
使用モジュール
Python 3.4以降では標準モジュールに含まれているpathlibを使用しますので、インストールは不要です。
インストール:不要
モジュールのインポート
pathlibモジュールのPathクラスをインポートします。
1 | from pathlib import Path |
ディレクトリ構成
D:\PythonScript\python-work\code でスクリプトを実行します。
└── temp
├── sub1
| ├── file1.txt
| └── file1.bmp
└── sub2
| ├── file2.txt
| └── file2.bmp
├── file.txt
└── file.bmp
Pathオブジェクトの生成
Path()
の引数にパスを含む文字列を指定する事でPathオブジェクトを生成します。
1 2 3 | tmp_dir = Path('temp') print(type(tmp_dir)) # <class 'pathlib.WindowsPath'> |
実行環境がWindowsの場合、WindowsPathオブジェクトになります。
カレントディレクトリの取得
カレントディレクトリ(作業ディレクトリ)を取得するには、getcwd()
メソッドを使用します。
またはPath()
でも取得可能ですが、結果は相対パスになります。絶対パスに変換するためにはresolve()
を使用します。
または
Path()
1 2 3 | path = Path.cwd() print(path) # D:\PythonScript\python-work\code |
1 2 3 4 5 6 | path = Path() print(path) # . print(path.resolve()) # D:\PythonScript\python-work\code |
パスの連結
Path
オブジェクトに対して/
演算子を使うとパスが連結できます。
1 2 3 4 5 6 7 | tmp_sub1 = tmp_dir / 'sub1' print(tmp_sub1) # temp\sub1 tmp_sub1_file = tmp_dir / 'sub1' / 'file1.txt' print(tmp_sub1_file) # temp\sub1\file1.txt |
joinpath()
メソッドでも連結が可能です。複数のパスを連結する場合は、引数を複数指定します。
1 2 3 | tmp_sub1_file = tmp_dir.joinpath('sub1', 'file1.txt') print(tmp_sub1_file) # temp\sub1\file1.txt |
親ディレクトリへ移動
相対パス..
を連結すると親ディレクトリ(上位ディレクトリ)へ移動できます。
1 2 3 | tmp_sub1_img = tmp_sub1_file.joinpath('..', 'img1.bmp') print(tmp_sub1_img) # temp\sub1\file.txt\..\img1.bmp |
結果は相対パスとなるため絶対パスに変換するには、absolute()
か resolve()
を使用します。
1 2 | print(tmp_sub1_img.resolve()) # temp\sub1\img1.bmp |
parent
プロパティでも親ディレクトリに移動できます。
1 2 3 | tmp_sub1_img = tmp_sub1_file.parent / 'img1.bmp' print(tmp_sub1_img) # temp\sub1\img1.bmp |
またparents
プロパティでインデックスを指定することで移動する階層を選択することができます。
1 2 3 4 5 6 7 8 | print(tmp_sub1_file.parents[0]) # temp/sub1 print(tmp_sub1_file.parents[1]) # temp tmp_sub1_file.parents[2] # . |
パスの存在確認
パスの存在確認にはexist()
メソッドを使用します。結果はブール型(True/False)で返されます。
1 2 3 4 5 6 7 | tmp_sub1_file = tmp_dir.joinpath('sub1', 'file1.txt') print(tmp_sub1_file.exists()) # True tmp_sub2_file = tmp_dir.joinpath('sub2', 'file1.txt') print(tmp_sub2_file1.exists()) # False |
ファイル名・拡張子の取得
ファイル名取得は name
、拡張子は suffix
、拡張子を除いたファイル名は stem
プロパティを指定します。
Pathオブジェクト.suffix
Pathオブジェクト.stem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # ファイル名の取得 f_name = tmp_sub1_file.name print(f_name) # file1.txt # 拡張子の取得 ext_name = tmp_sub1_file.suffix print(ext_name) # .txt # 拡張子抜きのファイル名の取得 name = tmp_sub1_file.stem print(name) # file1 |
ファイル名・拡張子を変更
ファイル名や拡張子を変更する事ができます。ファイル名は with_name
、拡張子は with_suffix
、拡張子を除いたファイル名は with_stem
を使用します。
Pathオブジェクト.with_suffix(変更後の文字列)
Pathオブジェクト.with_stem(変更後の文字列)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | print(tmp_sub1_file) # tmep/sub1/file1.txt # ファイル名を変更 c_name = tmp_sub1_file.with_name('file3.pdf') print(c_name) # temp/sub1/file3.pdf # 拡張子を変更 c_suffix = tmp_sub1_file.with_suffix('.pdf') print(c_suffix) # temp\sub1\file1.pdf # 拡張子抜きファイル名を変更 c_stem = tmp_sub1_file.with_stem('file3') print(c_stem) # temp\sub1\file3.txt |
特定の文字列が含まれるか検索
パスに特定の文字列が含まれるかを検索するには、match()
メソッドを使用します。match
は右側から一致を調べるので、パターンの記述を合わせる必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | print(tmp_sub1_file) # temp\sub1\file1.txt tmp_sub1_file.match('sub1') # False tmp_sub1_file.match('*/sub1') # False tmp_sub1_file.match('sub1/*') # True tmp_sub1_file1.match('*.txt') # True |
絶対パスと相対パスの変換
以下のパスを例にします。
1 2 3 | rel_path = Path('temp/sub1') print(rel_path) # temp\sub1 |
相対パスを絶対パスに変換するには、resolve()
を使用します。
1 2 3 4 5 | for path in tmp_dir.rglob('*.bmp'): print(path) # temp\sub1\file1.bmp # temp\sub2\file2.bmp |
1 2 3 | abs_path = rel_path.resolve() print(abs_path) # D:\PythonScript\python-work\code\temp\sub1 |
相対パスに..
が含まれている場合、正しく解釈され絶対パスに変換されます。
1 2 3 4 5 6 | tmp_sub2_file = tmp_sub1_file.joinpath('../..', 'sub2/file2.txt') print(tmp_sub2_file) # temp\sub1\file1.txt\..\..\sub2\file2.txt print(tmp_sub2_file.resolve()) D:\PythonScript\python-work\code\temp\sub2\file2.txt |
絶対パスを相対パスに変換するには、relative_to()
を使用します。引数には基点となるパスを指定します。
1 2 3 4 5 | print(abs_path.relative_to(Path.cwd())) # temp\sub1 print(abs_path.relative_to('D:\PythonScript\python-work\code')) # temp\sub1 |
引数に相対パスを指定することで、別のパスを基点とする相対パスに変更することも可能です。
1 2 3 4 | tmp = Path('temp') tmp_sub2_img = Path('temp/sub2/file2.bmp') p = tmp_sub2_img.relative_to(tmp) # sub2\file2.bmp |
Pathオブジェクトを文字列に変換する
Pathオブジェクトは文字列として取得したい場合は、str()
を使用します。
1 2 3 4 5 6 | s = str(tmp_sub1_file) print(s) # temp\sub1\file1.txt print(type(s)) # <class 'str'> |
ディレクトリ名とファイル名の一覧取得
ディレクトリ名とファイル名の一覧を取得するには iterdir()
メソッドを使用します。
取得結果はリストになります。
1 2 3 4 5 6 7 | for list in tmp_dir.iterdir(): print(list) # temp\file.bmp # temp\file.txt # temp\sub1 # temp\sub2 |
指定したパス直下の情報のみ取得できます。
サブディレクトリの中までを取得したい場合は、次に紹介する再帰的に取得する方法を使用します。
ディレクトリ名とファイル名を再帰的に取得
サブディレクトリも含め再帰的にディレクトリ名とファイル名を取得するには、rglob()
メソッドを使用します。引数にマッチさせるパターン文字列を指定します。
全てのファイルを対象にするには引数に '*'
を指定します。
1 2 3 4 5 6 7 8 9 | for path in tmp_dir.rglob('*'): print(path) # temp\sub1 # temp\sub2 # temp\sub1\file1.txt # temp\sub1\file1.bmp # temp\sub2\file2.txt # temp\sub2\file2.bmp |
拡張子.bmp
のファイルのみを取得する場合は、以下のように引数を指定します。
ディレクトリ名のみ取得
ディレクトリ名のみを取得したい場合は、is_dir()
メソッドでディレクトリ判定を行いTrue
のパスのみ取得します。
1 2 3 4 | [print(path) for path in tmp_dir.rglob('*') if path.is_dir()] # temp\sub1 # temp\sub2 |
ファイル名のみ取得
ファイル名のみを取得する場合は、is_file()
メソッドでファイル判定を行いTrue
のパスのみ取得します。
1 2 3 4 5 6 7 8 | [print(path) for path in tmp_dir.glob('*') if path.is_file()] # temp\file.bmp # temp\file.txt # temp\sub1\file1.bmp # temp\sub1\file1.txt # temp\sub2\file2.bmp # temp\sub2\file2.txt |
pathlibの使い方の解説は以上になります。
関連記事
・Pythonでカレントディレクトリを取得・変更
・Pythonでディレクトリ(フォルダ)・ファイルのコピー、移動(shutilモジュール)
・Pythonでディレクトリ名・ファイル名の一覧取得(os, globモジュール)
・Pythonでファイル名の一括変更(os, globモジュール)