Python, pathlibで絶対パスと相対パスを相互変換・判定

Pythonのpathlibモジュールを使ってファイル・ディレクトリ(フォルダ)の絶対パスと相対パスを相互変換および判定する方法を説明します。 pathlibはPython3.4から追加されたモジュール。ファイルやディレクトリのパスをオブジェクトとして操作できます。標準ライブラリに含まれているので追加のインストールは不要(importは必要)。

pathlib --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

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

絶対パスと相対パス pathlibの基本 カレントディレクトリを取得: cwd() 相対パスを絶対パスに変換: resolve() 絶対パスを相対パスに変換: relative_to() 絶対パスか判定: is_absolute()

pathlibの基本的な使い方については

以下のようなファイル・ディレクトリ構成を例とします。 temp ├── dir │ └── sub_dir │ └── file2.txt └── file.txt

絶対パスと相対パス

はじめに絶対パスと相対パスについて簡単に説明します。 Wikipedia英語版に具体的な例を含む説明があります。

Path (computing) - 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オブジェクトを取得できます。

pathlib - cwd() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

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オブジェクトが返されます。

pathlib - resolve() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

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()を使います。

pathlib - relative_to() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

引数に指定したパスを起点とする相対パスに変換されます。 例えば、カレントディレクトリを起点とする相対パスに変換したい場合は上述の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
Last Updated: 6/26/2019, 10:34:03 PM