Python, pathlibで絶対パスと相対パスを相互変換・判定
Pythonのpathlibモジュールを使ってファイル・ディレクトリ(フォルダ)の絶対パスと相対パスを相互変換および判定する方法を説明する。
pathlibはPython3.4から追加されたモジュール。ファイルやディレクトリのパスをオブジェクトとして操作できる。標準ライブラリに含まれているので追加のインストールは不要(import
は必要)。
ここでは以下の内容について説明する。
- 絶対パスと相対パス
- pathlibの基本
- カレントディレクトリを取得:
cwd()
- 相対パスを絶対パスに変換:
resolve()
- 絶対パスを相対パスに変換:
relative_to()
- 絶対パスか判定:
is_absolute()
pathlibの基本的な使い方については以下の記事を参照。
以下のようなファイル・ディレクトリ構成を例とする。
temp
├── dir
│ └── sub_dir
│ └── file2.txt
└── file.txt
絶対パスと相対パス
はじめに絶対パスと相対パスについて簡単に説明する。
Wikipedia英語版に具体的な例を含む説明がある。
絶対パス(absolute path)
絶対パスは、ファイルやディレクトリを一意に示すパス。
Macを含むUnix系OSでは/
から始まり、Windowsではドライブ文字や\\
(サーバーの場合)から始まる。
- Unix(Mac含む):
/Users/xxx/Documents/
- WIndows:
C:\Program Files
or\\servername\
相対パス(relative path)
相対パスは、あるディレクトリ(カレントディレクトリ)からの相対的なファイルやディレクトリの位置を示すパス。カレントディレクトリによって同じファイルやディレクトリでも異なるパスで表される。
例えば、/Users/xxx/Documents/file.txt
というファイルの相対パスは、
/Users/
をカレントディレクトリとした場合xxx/Documents/file.txt
/Users/xxx/
をカレントディレクトリとした場合Documents/file.txt
のように表される。
相対パスでは現在のパスを明示的に示す.
や、一つ上の階層を示す..
などが使える。
/Users/xxx/Documents/
をカレントディレクトリとした場合、..
は/Users/xxx/
に相当する。
pathlibの基本
pathlib.Path()
でPath
オブジェクトを生成して操作する。引数に相対パスまたは絶対パスでパスを指定する。
import pathlib
import os
p = pathlib.Path('temp/file.txt')
print(p)
# temp/file.txt
print(type(p))
# <class 'pathlib.PosixPath'>
OSによってPosixPath
またはWindowsPath
のインスタンスとなる。
詳しくは以下の記事を参照。
カレントディレクトリを取得: cwd()
Path
のcwd()
でカレントディレクトリの絶対パスのPath
オブジェクトを取得できる。
print(p.cwd())
# /Users/mbp/Documents/my-project/python-snippets/notebook
print(type(p.cwd()))
# <class 'pathlib.PosixPath'>
以下のようにも書ける。
print(pathlib.Path.cwd())
# /Users/mbp/Documents/my-project/python-snippets/notebook
print(type(pathlib.Path.cwd()))
# <class 'pathlib.PosixPath'>
同じくカレントディレクトリを返すos.getcwd()
はパスを文字列(str
)で返す。
print(os.getcwd())
# /Users/mbp/Documents/my-project/python-snippets/notebook
print(type(os.getcwd()))
# <class 'str'>
pathlibにはカレントディレクトリを変更するメソッドはない。os.chdir()
を使う。
相対パスを絶対パスに変換: resolve()
以下のPath
オブジェクトを例とする。
p = pathlib.Path('temp/file.txt')
print(p)
# temp/file.txt
相対パスを絶対パスに変換するにはresolve()
を使う。Path
オブジェクトが返される。
print(p.resolve())
# /Users/mbp/Documents/my-project/python-snippets/notebook/temp/file.txt
相対パスに..
が含まれている場合、正しく解釈された上で除去されて絶対パスに変換される。
p_rel = pathlib.Path('temp/dir/../file.txt')
print(p_rel)
# temp/dir/../file.txt
print(p_rel.resolve())
# /Users/mbp/Documents/my-project/python-snippets/notebook/temp/file.txt
絶対パスを相対パスに変換: relative_to()
以下のPath
オブジェクトを例とする。絶対パスを指定して生成している。
p_abs = pathlib.Path('/Users/mbp/Documents/my-project/python-snippets/notebook/temp/file.txt')
print(p_abs)
# /Users/mbp/Documents/my-project/python-snippets/notebook/temp/file.txt
絶対パスを相対パスに変換するにはrelative_to()
を使う。
引数に指定したパスを起点とする相対パスに変換される。
例えば、カレントディレクトリを起点とする相対パスに変換したい場合は上述のcwd()
を使って以下のように書ける。
print(p_abs.relative_to(p.cwd()))
# temp/file.txt
引数はPath
オブジェクトではなくパスの文字列でも指定可能。カレントディレクトリ以外のディレクトリを起点とする例は以下の通り。
print(p_abs.relative_to('/Users/mbp/Documents/my-project'))
# python-snippets/notebook/temp/file.txt
ルートやドライブが異なっているなど、変換が不可能なディレクトリを引数に指定するとエラーとなる。
# print(p_abs.relative_to('/usr/'))
# ValueError: '/Users/mbp/Documents/my-project/python-snippets/notebook/temp/file.txt' does not start with '/usr'
便宜上、絶対パスを相対パスに変換と書いたが、相対パスを別のパスを起点とする相対パスに変換することも可能。
p_rel = pathlib.Path('temp/dir/sub_dir/file2.txt')
print(p_rel.relative_to('temp/dir'))
# sub_dir/file2.txt
絶対パスか判定: is_absolute()
Path
オブジェクトが絶対パスかを判定するにはis_absolute()
を使う。
print(p_abs)
# /Users/mbp/Documents/my-project/python-snippets/notebook/temp/file.txt
print(p_abs.is_absolute())
# True
is_absolute()
がFalse
であれば相対パス。相対パスかを判定するメソッドはない。
print(p_rel)
# temp/dir/sub_dir/file2.txt
print(p_rel.is_absolute())
# False