Traffine I/O

日本語

2023-03-10

ファイルシステム操作を簡素化するPathlibモジュール

pathlib とは

Pathlibは、ファイルシステムとやりとりする方法を簡素化するためのPython標準ライブラリの1つである。ファイルパスを表現するためのオブジェクト指向のインタフェースを提供し、ファイルの読み取り、書き込み、操作などの一般的なファイルシステム操作に使用できるメソッドを提供する。

Python 3.4以前は、開発者はファイルシステム操作にosos.pathモジュールを依存する必要がありました。しかし、これらのモジュールはやや使いにくく、pathlibが提供するオブジェクト指向のインタフェースが欠けていました。

Pathlibは、高レベルなインターフェースを提供することで、パスやファイルを操作することを簡素化します。Pathlibを使用すると、プラットフォーム固有のパスセパレータを気にする必要がなく、文字列操作を使用してパスを連結することを気にする必要もありません。ファイルとディレクトリの作成、読み取り、書き込み、操作が簡単に行えます。

pathlib の基本的な使い方

この記事では、pathlibの基本的な使い方と、ファイルパスを扱う方法の簡素化について説明します。

パスの作成

Pathオブジェクトを作成するには、Pathコンストラクタにパスを表す文字列を渡します。

python
from pathlib import Path

# Create a path object
path = Path('/usr/local/bin')

また、相対パスを使用してPathオブジェクトを作成することもできます。

python
# Create a path object using a relative path
path = Path('foo/bar')

パスの操作

Pathlibには、パスを操作するための多数のメソッドが用意されています。その中でももっとも一般的なのはjoinpath()メソッドで、2つのパスを結合することができます。例えば以下のようになります。

python
# Join two paths
path = Path('/usr/local').joinpath('bin')

また、parentnamesuffixなどの属性を使用してパスの個々の部分にアクセスすることもできます。例えば以下のようになります。

python
# Access parts of a path
path = Path('/usr/local/bin/python3')
print(path.parent)  # /usr/local/bin
print(path.name)  # python3
print(path.suffix)  # .py

Pathlibは、パスが存在するかどうかを確認したり、ファイルサイズを取得したり、ファイルを削除するためのメソッドも提供しています。

python
# Check if a path exists
print(path.exists())

# Get the size of a file
print(path.stat().st_size)

# Delete a file
path.unlink()

Path オブジェクトのメソッド

Pathlibの中心には、Pathクラスがあります。Pathオブジェクトは、プラットフォームに依存しない方法でファイルまたはディレクトリのパスを表します。 Pathオブジェクトには、ファイルとディレクトリのパスを操作するために使用できる多数のメソッドが用意されています。この記事では、PathlibのPathオブジェクトの中でももっとも一般的に使用されるメソッドのいくつかを紹介します。

exists()

exists()はファイルやディレクトリが存在する場合にはTrue、存在しない場合にはFalseを返します。

python
from pathlib import Path

# Create a Path object
file_path = Path('/path/to/my/file')

# Check if the file exists
if file_path.exists():
    print('The file exists!')

is_file()

is_file()はパスがファイルを表す場合にはTrue、そうでない場合にはFalseを返します。

python
from pathlib import Path

# Create a Path object
file_path = Path('/path/to/my/file')

# Check if the path is a file
if file_path.is_file():
    print('The path is a file!')

is_dir()

is_dir()はパスがディレクトリを表す場合にはTrue、そうでない場合にはFalseを返します。

python
from pathlib import Path

# Create a Path object
dir_path = Path('/path/to/my/directory')

# Check if the path is a directory
if dir_path.is_dir():
    print('The path is a directory!')

name

nameはパスを除いたファイルまたはディレクトリの名前を返します。

python
from pathlib import Path

# Create a Path object
file_path = Path('/path/to/my/file')

# Get the name of the file
file_name = file_path.name
print('File name:', file_name)

parent

parentは、ファイルまたはディレクトリの親ディレクトリを返します。

python
from pathlib import Path

# Create a Path object
file_path = Path('/path/to/my/file')

# Get the parent directory of the file
parent_dir = file_path.parent
print('Parent directory:', parent_dir)

absolute()

absolute()は、ファイルまたはディレクトリの絶対パスを返します。

python
from pathlib import Path

# Create a Path object
file_path = Path('/path/to/my/file')

# Get the absolute path of the file
abs_path = file_path.absolute()
print('Absolute path:', abs_path)

glob(pattern)

glob(pattern)は、指定されたパターンに一致するPathオブジェクトのリストを返します。

python
from pathlib import Path

# Create a Path object for a directory
dir_path = Path('/path/to/my/directory')

# Get a list of all the PDF files in the directory
pdf_files = dir_path.glob('*.pdf')
for pdf_file in pdf_files:
    print(pdf_file)

cwd()

cwd()は、現在の作業ディレクトリを表すPathオブジェクトを返します。

python
from pathlib import Path

current_directory = Path.cwd()

print(f"Current directory: {current_directory}")

絶対パスと相対パス

Pathlibは、Pathオブジェクトのresolve()relative_to()メソッドを使用して、絶対パスと相対パスの変換方法を提供しています。

resolve()メソッドは、相対パスを絶対パスに変換するために使用されます。引数を取らず、絶対パスを表す新しいPathオブジェクトを返します。以下は例です。

python
from pathlib import Path

relative_path = Path('my_folder', 'my_file.txt')
absolute_path = relative_path.resolve()

print(f'Relative path: {relative_path}')
print(f'Absolute path: {absolute_path}')

この例では、相対パスmy_folder/my_file.txtを表す新しいPathオブジェクトを作成します。 次に、resolve()メソッドを使用して、それを絶対パスに変換します。出力は次のようになります。

python
Relative path: my_folder/my_file.txt
Absolute path: /full/path/to/my_folder/my_file.txt

relative_to()メソッドは、絶対パスを相対パスに変換するために使用されます。結果の相対パスが相対的であるべき基本ディレクトリが1つの引数を取ります。以下は例です。

python
from pathlib import Path

base_path = Path('/full/path/to/my_folder')
absolute_path = Path('/full/path/to/my_folder/my_file.txt')
relative_path = absolute_path.relative_to(base_path)

print(f'Absolute path: {absolute_path}')
print(f'Relative path: {relative_path}')

この例では、2つのPathオブジェクトを作成しています。一つは、絶対パス/full/path/to/my_folder/my_file.txtを表し、もう一つは、基本ディレクトリ/full/path/to/my_folderを表しています。 次に、relative_to()メソッドを使用して、絶対パスを基本ディレクトリを基準とした相対パスに変換します。出力は次のようになります。

python
Absolute path: /full/path/to/my_folder/my_file.txt
Relative path: my_file.txt

これらのメソッドを使用することで、ファイルやディレクトリの場所に関係なく、コード内で簡単に絶対パスと相対パスを変換することができます。

パスの結合

Pythonでファイルやディレクトリのパスを扱う際には、パスを結合する操作がよく行われます。pathlibモジュールのPathオブジェクトは、joinpath()メソッドを使用して簡単にパスを結合することができます。

joinpath()メソッドは、1つ以上の引数を受け取ることができます。引数は文字列または他のPathオブジェクトである必要があります。これらのパスを連結して、新しいPathオブジェクトを作成します。以下は例です。

python
from pathlib import Path

path1 = Path('/Users/myuser')
path2 = Path('Documents', 'file.txt')

full_path = path1.joinpath(path2)

print(full_path)

この例では、パス/Users/myuserDocuments/file.txtを表す2つのPathオブジェクトを作成します。joinpath()メソッドを使用してこれらのパスを連結し、完全なパス/Users/myuser/Documents/file.txtを表す新しいPathオブジェクトを作成します。

また、複数の引数をjoinpath()に一度に渡すこともできます。以下のようになります。

python
from pathlib import Path

path1 = Path('/Users/myuser')
path2 = 'Documents'
path3 = 'file.txt'

full_path = path1.joinpath(path2, path3)

print(full_path)

これにより、前の例と同じ出力が生成されます。

また、/演算子を使用してパスを結合することもできます。これは、joinpath()を呼び出すのと同等です。次に例を示します。

python
from pathlib import Path

path1 = Path('/Users/myuser')
path2 = Path('Documents')
path3 = Path('file.txt')

full_path = path1 / path2 / path3

print(full_path)

これにより、前の例と同じ出力が生成されます。

pathlib による例外処理

ファイルやディレクトリを扱うプログラムでは、常にエラーが発生する可能性があります。例えば、ファイルが存在しない、ディレクトリに書き込みできない、プログラムがファイルにアクセスするために必要な権限がないなどが挙げられます。Pythonでは、例外を使用してこれらのエラーを処理し、優雅に対処することができます。この記事では、pathlibを使用した例外処理の方法について説明します。

Pathlib における例外

Pathlibは、エラーが発生した場合に例外を発生させます。これらの例外は、基底クラスOSErrorから派生しており、エラーに関する追加情報を提供します。pathlibでよく発生する例外には、以下のものがあります。

  • FileNotFoundError: ファイルまたはディレクトリが存在しない場合に発生します。
  • PermissionError: プログラムがファイルまたはディレクトリにアクセスするための十分な権限がない場合に発生します。
  • NotADirectoryError: ディレクトリであると期待されているパスが実際にはディレクトリでない場合に発生します。

Try-Except ブロックによる例外処理

pathlibで発生した例外を処理するには、try-exceptブロックを使用できます。これにより、エラーを優雅に処理し、プログラムがクラッシュするのを防止することができます。以下に例を示します。

python
from pathlib import Path

# Create a path object for a file
file_path = Path('/path/to/my/file')

try:
    # Open the file for reading
    with file_path.open() as f:
        contents = f.read()
except FileNotFoundError:
    # Handle the error if the file doesn't exist
    print('Error: File does not exist.')
except PermissionError:
    # Handle the error if we don't have permission to access the file
    print('Error: Permission denied.')

この例では、open()メソッドを使用してファイルを読み取りモードで開こうとしています。ファイルが存在しない場合は、FileNotFoundError例外をキャッチしてエラーメッセージを表示します。同様に、ファイルにアクセスする権限がない場合は、PermissionError例外をキャッチして別のエラーメッセージを表示します。

Path Manager クラスの例

絶対パスと相対パスを返すパスマネージャークラスのサンプルコードを紹介します。

python
from pathlib import Path

class PathManager:
    def __init__(self):
        self.root_path = Path(__file__).resolve().parents[2]

    def get_absolute_path(self, path_str):
        path = Path(path_str)
        return path.resolve()

    def get_relative_path(self, path_str):
        path = Path(path_str)
        return path.relative_to(self.root_path)

__init__メソッドは、現在のファイルの3番目の親ディレクトリをroot_path属性に設定し、相対パスの基準として使用できます。

get_absolute_pathメソッドは、パス文字列を受け取り、Pathクラスのresolve()メソッドを使用して絶対パスを返します。

get_relative_pathメソッドは、パス文字列を受け取り、Pathクラスのrelative_to()メソッドを使用してroot_pathからの相対パスを返します。

以下のようにクラスを使用できます。

python
pm = PathManager()
abs_path = pm.get_absolute_path("data/file.txt")
rel_path = pm.get_relative_path("src/utils.py")

参考

https://docs.python.org/3/library/pathlib.html

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!