[解決!Python]pathlib.Path.joinpathメソッドを使ってパスを結合するには解決!Python

pathlibモジュールのPathクラスが提供するjoinpathメソッドを使って相対パスや絶対パスを結合する方法を紹介する。

» 2022年11月29日 05時00分 公開
[かわさきしんじDeep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

from pathlib import Path

# UNIX系統のOSの場合
# 相対パスの結合
path = Path('foo')
result = path.joinpath('bar', Path('baz'))
print(result)  # foo/bar/baz

# 絶対パスの結合
path = Path('/foo')
result = path.joinpath('bar', 'baz.txt')
print(result)  # /foo/bar/baz.txt

# 引数の途中に絶対パスが含まれている場合
path = Path('foo')
result = path.joinpath('bar', '/baz', 'qux')
print(result)  # /baz/qux

# os.path.join関数とは異なり空文字列を最後においてもパス区切り文字は付加されない
from os.path import join
path = Path('foo')
result = join(path, '')
print(result)  # foo/

result = path.joinpath(Path(''))
print(result)  # foo

data = Path('data')
start_year = 2020
end_year = 2022
for year in range(start_year, end_year+1):
    for month in range(1, 13):
        path = data.joinpath(f'{year}', f'{month:02}')
        # data/2020/01、data/2020/02などのパスを使って何らかの処理を行う
        somefile = path.joinpath('somefile.txt')
        print(somefile)


# Windowsの場合
# 相対パスの結合
path = Path('foo')
result = path.joinpath('bar', 'baz.txt')
print(result)  # foo\bar\baz.txt

# 絶対パスの結合
path = Path('\\foo')
result = path.joinpath('bar', 'baz.txt')
print(result)  # \foo\bar\baz.txt

# 引数の途中に絶対パスが含まれている場合
path = Path('foo')
result = path.joinpath('bar', '\\baz', 'qux')
print(result)  # \baz\qux

# 絶対パスの結合(ドライブ文字を含む)
path = Path('c:')
result = path.joinpath('\\foo', 'bar', 'baz.txt')
print(result)  # c:\foo\bar\baz.txt

path = Path('c:')
result = path.joinpath('foo', '\\bar', 'baz.txt')
print(result)  # c:\bar\baz.txt

# ドライブ文字とパスだけを含む場合
path = Path('d:')
result = path.joinpath('foo')
print(result)  # d:foo

# os.path.join関数とは異なり空文字列を最後においてもパス区切り文字は付加されない
from os.path import join
path = Path('foo')
result = join(path, '')
print(result)  # foo\

result = path.joinpath(Path(''))
print(result)  # foo

data = Path('data')
start_year = 2020
end_year = 2022
for year in range(start_year, end_year+1):
    for month in range(1, 13):
        path = data.joinpath(f'{year}', f'{month:02}')
        # data\2020\01、data\2020\02などのパスを使って何らかの処理を行う
        somefile = path.joinpath('somefile.txt')
        print(somefile)


pathlib.Pathクラスのjoinpathメソッドを使ったパスの結合

 pathlibモジュールのPathクラスのインスタンスにはjoinpathメソッドがある(実際にはPathクラスの基底クラスであるPurePathクラスがこのメソッドをを提供している)。このメソッドを使うと、Pathクラスのインスタンスと引数に指定したパス構成要素を基に、新たなパスを表すPathオブジェクトを生成できる。

 このメソッドの動作は次のようになっている。

  • joinpathメソッドの引数に絶対パスが含まれていない場合:Pathオブジェクトの値をパスのトップレベルとして、引数に指定したパス構成要素をつないだものを返送する
  • joinpathメソッドの引数に絶対パスが含まれている場合:最後に指定された絶対パスとそれ以降に指定されているパス構成要素をつないだものを返送する

 簡単な例を以下に示す(macOSで実行した例)。

from pathlib import Path

path = Path('foo')
result = path.joinpath('bar', Path('baz'))
print(result)  # foo/bar/baz


 この例ではjoinpathメソッドの呼び出しに使用しているPathオブジェクトは「foo」という相対パスを表している。また、joinpathメソッドの引数には'bar'とPath('baz')の2つの相対パスを表す値が渡されている(このようにjoinpathメソッドには文字列やPathクラスのインスタンスを渡せることにも注目)。そのため、joinpathはこれらを結合した結果である「foo/bar/baz」を表すPathオブジェクトを返送する。

 これはWindowsでも同様だ。Windows上で実行した例を以下に示す。パス区切り文字が異なることを除けば同じ結果が得られている。

from pathlib import Path

path = Path('foo')
result = path.joinpath('bar', 'baz.txt')
print(result)  # foo\bar\baz.txt


 絶対パスを結合するには次の2つの方法がある。

  • 絶対パスを参照するPathオブジェクトでjoinpathメソッドを呼び出して、結合したいパスを指定する
  • joinpathメソッドを呼び出して、その引数に絶対パスを含むパス構成要素を指定する

 前者の例を以下に示す(macOS)。

path = Path('/foo')
result = path.joinpath('bar', 'baz.txt')
print(result)  # /foo/bar/baz.txt


 この例では変数pathは「/foo」という絶対パスを参照している。そして、このオブジェクトでjoinpathメソッドを呼び出しているので、引数に指定した2つのパス構成要素「bar」と「baz.txt」をパス区切り文字でつないだものが戻り値となっている。

 以下はjoinpathメソッドの引数に絶対パスを含めた例だ(macOS)。

path = Path('foo')
result = path.joinpath('bar', '/baz', 'qux')
print(result)  # /baz/qux


 この例では、joinpathメソッドの呼び出しに使用しているPathオブジェクトは相対パスを参照しているが、引数には「/baz」という絶対パスが含まれている。このような場合、呼び出しに使用したオブジェクトの値や絶対パスよりも前に指定されているパス構成要素は無視されて、(最後に指定された)絶対パスとそれ以降の構成要素をつないだものが戻り値となる。そのため、戻り値の値は絶対パスである「/baz」とその後にある「qux」をつないだ「/baz/qux」となっている。

 Windowsでもパス区切りがバックスラッシュ「\」になることとそのエスケープが必要になること(があるの)を除けば、基本的な動作は同様だ。

path = Path('\\foo')
result = path.joinpath('bar', 'baz.txt')
print(result)  # \foo\bar\baz.txt


 この例は、バックスラッシュとそのエスケープを除けば、先ほどのmacOSの例と同様なコードであり、結果も同様だ。以下はjoinpathメソッドの引数に絶対パスを含んだ例だが、これも同様だ。

path = Path('foo')
result = path.joinpath('bar', '\\baz', 'qux')
print(result)  # \baz\qux


 ただし、Windowsにはドライブ文字という概念があるので、そこには注意が必要だ。以下はドライブ文字、ルートディレクトリ、サブディレクトリ、ファイルで構成されるパスを結合する例だ。

path = Path('c:')
result = path.joinpath('\\foo', 'bar', 'baz.txt')
print(result)  # c:\foo\bar\baz.txt


 ドライブ文字と絶対パスと他の構成要素を結合する例を以下に示す。

path = Path('c:')
result = path.joinpath('foo', '\\bar', 'baz.txt')
print(result)  # c:\bar\baz.txt


 この場合、ドライブ文字である「c:」は有効だが、絶対パスである「\\bar」よりも前にある「foo」は無視されて「c:\bar\baz.txt」というパスが得られている。

 以下はドライブ文字と相対パスを結合する例だ。

path = Path('d:')
result = path.joinpath('foo')
print(result)  # d:foo


 この場合は、パスはあくまでもDドライブのカレントディレクトリにあるfooというパスを表すことになる。

 joinpathメソッドを使うと、各種の要素で構成されるパスを機械的に扱って、処理対象のパスを自動的に生成できる。例えば、dataディレクトリの下に年、月ごとに作成されたディレクトリがあり、さらにその下にあるファイルを対象に何かの処理を行うとすると、以下のようなコードが書けるだろう。

data = Path('data')
start_year = 2020
end_year = 2022
for year in range(start_year, end_year+1):
    for month in range(1, 13):
        path = data.joinpath(f'{year}', f'{month:02}')
        # data/2020/01、data/2020/02などのパスを使って何らかの処理を行う
        somefile = path.joinpath('somefile.txt')
        print(somefile)


 これを実行すると、以下のようなパスを自動的に生成できる(Windowsではパス区切り文字が異なる以外は同様な結果となる)。

>>> data = Path('data')
>>> start_year = 2020
>>> end_year = 2022
>>> for year in range(start_year, end_year+1):
...     for month in range(1, 13):
...         path = data.joinpath(f'{year}', f'{month:02}')
...         # data/2020/01、data/2020/02などのパスを使って何らかの処理を行う
...         somefile = path.joinpath('somefile.txt')
...         print(somefile)
...
data/2020/01/somefile.txt
data/2020/02/somefile.txt
    # ……省略……
data/2022/11/somefile.txt
data/2022/12/somefile.txt



「解決!Python」のインデックス

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。