連載
» 2019年10月29日 05時00分 公開

Python入門:[Python入門]pathlib.Pathクラスによるパス操作 (1/3)

pathlibモジュールが提供するPathクラス、PurePathクラスなどを使って、ファイルやディレクトリを扱う方法を紹介する。

[かわさきしんじ,Deep Insider編集部]

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

「Python入門」のインデックス

連載目次

 前回はosモジュールとos.pathモジュールを使用してのファイル/ディレクトリ操作の基本を見た。今回はPython 3.4で導入された比較的新しいpathlibモジュールを使って、同様な操作を行う方法を見てみよう。簡単なファイルの読み書きもサポートしているので、覚えておくと便利に使えるかもしれない。

pathlibモジュール

 Python 3.4で導入されたpathlibモジュールは、PythonでUNIXやWindowsのファイルやディレクトリ(のパス)を扱うためのものだ。UNIXとWindowsではパスの表記が異なることから(例えば、区切り文字、ドライブ文字の有無など)、pathlibモジュールではそれらを適切に扱えるような仕組みを用意している。

 まず、pathlibモジュールでは「純粋パス」と「具象パス」を表すクラスを3つ定義している。

  • PurePathクラス:PurePosixPathクラスとPureWindowsPathクラスの基底クラス
  • PurePosixPathクラス:UNIX系のOSにおけるパスを表現するクラス
  • PureWindowsPathクラス:Windowsにおけるパスを表現するクラス

 「純粋パス」というのは、実際にはOSのファイルシステムへのアクセスを行わない(実際にファイルやディレクトリにアクセスしようとして例外が発生することがない)。そのため、UNIX系のOSでWindows上のパス操作の確認などを行いたいときなどに使用できる。

 これに対して、「具象パス」とは実際にPythonのコードを実行している環境に合わせて、OSレベルのシステムコールが実行されることもある。「具象パス」についてもpathlibモジュールでは以下の3つのクラスが定義されている。

  • Pathクラス:PosixPathクラスとWindowsPathクラスの基底クラス
  • PosixPathクラス:UNIX系のOSにおけるパスを表す具象パスクラス
  • WindowsPathクラス:Windowsにおけるパスを表す具象パスクラス

 実際のクラス階層は次のようになっている。

pathlibモジュールで定義されているクラスの階層構造 pathlibモジュールで定義されているクラスの階層構造

 PurePath以下の純粋パスクラスは論理的なパスを扱うための機能を提供し、それらから派生する具象パスクラスは実際のファイルシステムへのアクセスを担うと考えるとよいだろう。純粋パスクラスは、パスを文字列のようなものとして捉え、拡張子の取り出しやパスの分割など、ファイルシステムを扱う際にあると便利な操作をメソッドや属性として用意したものとしても考えられる。これに対して、具象パスは実際のファイルシステム上に存在しているパス(ファイルやディレクトリ)を扱うための機能を提供する(例えば、ファイルが存在するかどうかを調べたり、ファイルの内容を読み出したり、ファイルに書き込みをしたりする機能がある)。

 実際には、PurePathクラスのインスタンスとPathクラスのインスタンスを生成すると、そのときに実行環境に合わせたクラスのインスタンスが生成される。例えば、以下のコードを実行して、UNIX系のOS上でPathクラスのインスタンスを生成すれば、実際にはPosixPathクラスのインスタンスとなり、同じコードをWindows上で実行すればWindowsPathクラスのインスタンスが生成される。

from pathlib import Path

mypath = Path('.')
print(type(mypath))

Pathクラスのインスタンスを生成して、その型を調べる

 このコードを、本連載で使用している「Try Jupyter」ページからたどれるJupyter Notebook環境で実行すると次のようになる。

実行結果 実行結果

 このようにPathクラスのインスタンスではなく、PosixPathクラスのインスタンスが生成されている。一方、Windows上でローカルに起動したJupyter Notebook環境では次のようになる。

実行結果 実行結果

 こちらではWindowsPathクラスのインスタンスが生成された。Pathクラスを介することで、コード上ではそれを実行する環境を抽象化しておいて、実際にコードを実行する(パスを操作する)ときには環境に応じた具体的なクラスのインスタンスが得られるようになっているということだ(これは、純粋パスについても同様だ)。

 このようにして作成したパスは、以下で紹介していく各種の属性やメソッドを使って操作することもできるが、以下のように除算演算子「/」を使って、パスを連結することも可能だ。

mypath = Path('foo')
newpath = mypath / 'bar' / Path('baz')
print(newpath)

除算演算子「/」を使ったパスの連結

 以下に実行結果を示す。

実行結果 実行結果

 なお、PurePathクラスやPathクラスのインスタンスは多くの場合、前回見たosモジュールやos.pathモジュールの引数としても指定できる。PurePathクラスやPathクラスのインスタンスを受け取ることができるものについては、Pythonのドキュメント「os --- 雑多なオペレーティングシステムインタフェース」などを参照されたい。ドキュメント中で「バージョン 3.6 で変更: os.PathLike インタフェースを実装したオブジェクトを受け入れるようになりました」とあるものがそうだ。

純粋パス

 実際のパス操作の話をする前に、PurePathクラスで定義されている属性やメソッドについて簡単にまとめておこう。以下にPurePathクラスで定義されている属性とメソッドを示す(一部。また、属性およびメソッド名の前の「PurePath.」は省略する)。

属性/メソッド 説明 対応するos.pathモジュールの関数
parts パスを構成要素に分割したもの(タプル) os.path.split関数
drive ドライブ文字 os.path.splitdrive(path)[0]
root インスタンスが絶対パスを表している場合には、そのルートの文字列  
anchor ドライブ文字とルートを結合したもの  
parent そのパスの上位パス os.path.dirname関数
name パスの末尾(ファイル名もしくはディレクトリ名) os.path.basename関数
suffix パスの末尾の要素に含まれる拡張子 os.path.splitext関数
suffixes パスの末尾の要素に含まれる複数の拡張子を要素とするリスト(tar.gzが拡張子であれば['.tar', '.gz']のようになる)  
stem パスの末尾の要素から拡張子を取り除いたもの  
as_posix() パスをPOSIX形式に変換する(ディレクトリの区切りをスラッシュ「/」とした表現にする)  
as_uri() パスをfile URI形式に変換する(相対パスを渡すと例外になる。Windowsではドライブ文字も必要になるので注意すること)  
is_absolute() パスが絶対パスか相対パスかを調べる os.path.isabs関数
joinpath(*others) パスを、*othersに与えたパスと結合する os.path.join関数
match(pattern) パスが、patternに与えたパターンにマッチするかを調べる  
relative_to(*other) パスから、*otherに与えたパスへの相対パスを取得する  
with_name(name) パスのname属性を、nameに与えた名前に変えたパスを取得する  
with_suffix(suffix) パスの拡張子を、suffixに与えたものに変更したパスを取得する  
PurePathクラスで定義されている属性/メソッド(一部)

 PurePathクラスの属性とメソッドは論理的なパスを操作するためのものに留まっている。とはいえ、複数の構成要素(複数のディレクトリとファイル)からなるパスを分割するような単純なものから、with_nameメソッドのように、既存の名前を別の名前に置き換えたパスを取得するなど、ファイルやディレクトリの名前を一括して変更するときに便利に使えるようなものまで用意されている。また、os.pathモジュールに含まれている機能に対応しているものもある。

 幾つかの利用例を以下に示す。

from pathlib import PurePath
import os

abspath = PurePath('/foo/bar/baz.txt'# 絶対パス
relpath = PurePath('xxx/yyy/zzz.txt'# 相対パス
print('type:', type(abspath))  # 実行する環境によって変化する
print('parts:', abspath.parts)  # 構成要素に分割
print('root:', abspath.root)  # ルートを表示
print('root:', relpath.root)  # ルートを表示(相対パスの場合)
print('parent:', abspath.parent)  # 上位パスの表示
print('name:', relpath.name)  # ファイル名
print('name:', os.path.basename('xxx/yyy/zzz.txt'))  # os.pathモジュールを使用
print('suffix:', abspath.suffix)  # 拡張子
print('stem:', abspath.stem)  # 拡張子以外のファイル名
print('stem + suffix:', abspath.stem + abspath.suffix)  # ファイル名全体
print('uri:', abspath.as_uri())  # URI形式(Windowsでは例外が発生するので注意)
print('is absolute:', relpath.is_absolute())  # 相対パスを「絶対パスか」調べる
print('joinpath:', Path('foo/bar').joinpath('baz', 'qux'))  # パスを結合
print('with name:', relpath.with_name('qux.txt')) # ファイル名を置き換え

PurePathクラスの属性/メソッドの使用例

 実行すると、次のようになる。コメントと合わせて見ながら、動作を確認してほしい。

実行結果 実行結果

 なお、Windows上で実行しているJupyter Notebook環境ではas_uriメソッドの呼び出しで例外が発生する。これはabspath変数の値が「/foo/bar/baz.txt」となっていて、Windowsにおける絶対パスとは異なるためだ。Windows上で実行している人は「c:/foo/bar/baz.txt」などに変更してみてほしい。

 これらの属性とメソッドは、PurePathクラスから派生している3つの具象パスクラスでも利用できる。というわけで、次に具象パスクラスについて見ていこう。

       1|2|3 次のページへ

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

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

メールマガジン登録

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