note.nkmk.me

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

Date: 2018-10-01 / tags: Python, ファイル操作

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()

Pathcwd()でカレントディレクトリの絶対パスの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
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事