【Python】ファイルパス/フォルダパスの分解と結合で便利なサンプル紹介(os、pathlib)

Pythonでフォルダやファイルのパス操作を行う際に便利なライブラリとして、従来のosモジュールと、新しいpathlibモジュールがあります。

それぞれに特徴があり、同じタスクを達成する方法が少し異なります。

この記事では、ファイルサイズや更新日時などのプロパティから、パス結合や分解といった基本操作について、ospathlibの両方について使い方を紹介しています。

単にファイルやフォルダのパスを操作を知りたい方だけでなく、どちらを選ぶべきか迷わずに使っている方も是非ご一読下さい。

目次

osとpathlibの違い

os モジュール

osは、Pythonに古くから存在する標準ライブラリで、ファイルやフォルダに関する低レベルな操作を行う機能が豊富に揃っています。os.pathサブモジュールを使えば、パスの結合や分解、ファイルやフォルダの状態確認など、基本的な操作が可能です。

長年の歴史があり、Python 2系から利用可能。
シンプルかつ軽量な関数が中心。
OS依存の処理も柔軟に対応。

pathlib モジュール

pathlibは、Python 3.4で導入された比較的新しいモジュールです。ファイルパスをオブジェクトとして扱うことを特徴としており、直感的かつオブジェクト指向的なコードを書くことができます。

パスを文字列ではなく「Pathオブジェクト」として扱う。
Pythonicな書き方を推奨し、コードの可読性が向上。
クロスプラットフォーム対応が容易。

どちらを選ぶべき?使用シーンの違い


ospathlibにはそれぞれの強みがあります。プロジェクトの規模やPythonのバージョン、開発スタイルに応じて適切な選択をすることが重要です。

比較項目ospathlib
可読性シンプルだが、文字列操作が多く冗長になることも。オブジェクト指向的で直感的なコードが書ける。
互換性Python 2系から利用可能でレガシーコードに最適。Python 3.4以降で使用可能。
柔軟性低レベルな操作に強い。クロスプラットフォーム対応が簡単。
学習コスト基本的な関数が多く、初心者でも扱いやすい。新しい概念(オブジェクト指向)に慣れる必要あり。
用途レガシーコードやシンプルなスクリプト向け。モダンなアプリケーションや大規模開発向け。
osとpathlibの基本概要

osとpathlibで用意されているパス操作の一覧

最初に、osモジュールとpathlibモジュールで用意されているパス操作について一覧で紹介しておきます。

機能ospathlib
パス結合os.path.join(path1, path2, ...)Path(path1).joinpath(path2, ...)
パス分解os.path.split(path)Path(path).parts
ファイル名取得os.path.basename(path)Path(path).name
フォルダ名取得os.path.dirname(path)Path(path).parent
拡張子取得os.path.splitext(path)Path(path).suffix
絶対パス化os.path.abspath(path)Path(path).resolve()
相対パス化os.path.relpath(path, start)Path(path).relative_to(start)
パス存在確認os.path.exists(path)Path(path).exists()
フォルダ判定os.path.isdir(path)Path(path).is_dir()
ファイル判定os.path.isfile(path)Path(path).is_file()
ファイル/フォルダ情報os.stat(path)Path(path).stat()

パスの結合

パスの結合は、os モジュールの join() 、または pathlibモジュールの joinpath() を使います。

import os

combined_path = os.path.join('C:/example_folder', 'subfolder/file.txt')
print(combined_path) 
from pathlib import Path

combined_path = Path('C:/example_folder').joinpath('subfolder/file.txt')
print(combined_path) 

どちらを使っても、以下の結果が得られます。

C:/example_folder/subfolder/file.txt

パスの分解

パスの分割は、os モジュールの split() 、または pathlibモジュールの partsを使います。
split()は フォルダパスと ファイル名の2つの値を常にタプルで返します。

import os

dirname, filename = os.path.split('C:/example_folder/subfolder/file.txt')
print(dirname) 
print(filename)

C:/example_folder/subfolder
file.txt


一方、partsも同じようにフォルダパスとファイル名は返してくれるものの、フォルダパスはフォルダ単位で分解された結果が返る点が異なります。

from pathlib import Path

parts = Path('C:/example_folder/subfolder/file.txt').parts
print(parts) 

以下の様に、ドライブ名、フォルダ名1,フォルダ名2,・・・ファイル名 に分解されて返されます。

('C:\', 'example_folder', 'subfolder', 'file.txt')

ファイル名、フォルダ名、拡張子の取得

os モジュールはメソッドとして、 pathlib モジュールはプロパティとしてファイル名、フォルダ名、拡張子を取得できます。

尚、os モジュールに用意されている splitext()は、2つの値が返されます。1つ目の値は、指定したパスから拡張子を取り除いた部分、2つ目の値は拡張子が返されるため、下記のサンプルでは1つ目の値を無視し、2つ目の値だけ取得するようにしています。

import os

# osモジュールを用いたファイル名、フォルダ名、拡張子の取得
path = 'C:/example_folder/subfolder/file.txt'
dirname = os.path.dirname(path) # フォルダ名の取得
filename = os.path.basename(path) # ファイル名の取得
 _ , extension = os.path.splitext(path) # 戻り値の1つ目を無視し、2つ目(拡張子)を取得

print(f'フォルダ名:{dirname}')  
print(f'ファイル名:{filename}') 
print(f'拡張子: {extension}') 
from pathlib import Path

# pathlib モジュールを用いたファイル名、フォルダ名、拡張子の取得
path = Path('C:/example_folder/subfolder/file.txt')
dirname = path.parent # フォルダ名の取得
filename  path.name # ファイル名の取得
extension = path.suffix # 拡張子の取得

print(f'フォルダ名:{dirname}')  
print(f'ファイル名:{filename}') 
print(f'拡張子: {extension}') 

フォルダ名:P:/MyPythonTool/PyTools
ファイル名:test.py
拡張子: .py

絶対パス化と相対パス化

絶対パス化は、カレントフォルダを起点にした相対パスを絶対パスに変換するものです。
os モジュールではpath.abspath() を、pathlibモジュールでは resolve()を使います。

import os

# os モジュールを使って相対パスから絶対パスを取得
absolute_path = os.path.abspath('example_folder/subfolder/file.txt')
print(f"絶対パス: {absolute_path}")  
from pathlib import Path

# pathlib モジュールを使って相対パスから絶対パスを取得
absolute_path = Path('example_folder/subfolder/file.txt').resolve()
print(f"絶対パス: {absolute_path}") 

絶対パス: C:/Users/username/current_directory/example_folder/subfolder/file.txt


相対パス化は、指定したパスを起点とした相対パスに変換するものです。
os モジュールではpath.relpath() を、pathlibモジュールでは relative_to()を使います。

import os

# os モジュールを使って絶対パスから相対パスを取得(start引数に起点となるパスを指定)
relative_path = os.path.relpath('C:/example_folder/subfolder/file.txt', start='C:/example_folder')
print(f"相対パス: {relative_path}") 
from pathlib import Path

# 絶対パスを指定
absolute_path = Path('C:/example_folder/subfolder/file.txt') # 変換したいパス
start_path = Path('C:/example_folder') # 起点となるパス

# pathlib モジュールを使って絶対パスから相対パスを取得
relative_path = absolute_path.relative_to(start_path)
print(f"相対パス: {relative_path}") 

相対パス: subfolder/file.txt

パス/ファイル/フォルダの存在確認

指定したパスがファイルかフォルダのどちらかであることを確認したい場合、osモジュール とpathlibモジュールの両方に用意されている exists() を使います。

ファイルとして存在しているか、あるいはフォルダとして存在しているかを確認したい場合、osモジュール ではisdir()isfile()を、pathlibモジュールでは is_dir()is_file()を使います。

import os

res = os.path.exists('C:/example_folder') # ファイル又はフォルダの存在確認(True or False)
res = os.path.isdir('C:/example_folder') # フォルダの存在確認(True or False)
res = os.path.isfile('C:/example_folder/file.txt') # ファイルの存在確認(True or False) 
from pathlib import Path

res = Path('C:/example_folder').exists() # ファイル又はフォルダの存在確認(True or False)
res = Path('C:/example_folder').is_dir() # フォルダの存在確認(True or False)
res = Path('C:/example_folder/file.txt').is_file() # ファイルの存在確認(True or False)

ファイル/フォルダ情報の取得

osモジュール、pathlibモジュール共に stat()を使って、ファイル/フォルダ情報(タイムスタンプやアクセス権など)を取得します。

どちらのモジュールを使っても、戻り値はos.stat_result クラスが返されます。このクラスのプロパティを参照することで、個々のファイル情報にアクセスできます。

尚、最終更新日時、作成日、アクセス日時は 1970年1月1日 00:00:00 UTC からの経過秒が返されるため、下記のサンプルでは 'yyyy/mm/dd hh:mm:ss' の形式に変換しています。

import os
import datetime

# ファイルのパスを指定
file_path = 'C:/Windows/notepad.exe'

# osモジュールを使用
stat = os.stat(file_path)
print(f"ファイルサイズ: {stat.st_size} バイト")
print(f"最終更新日時: {datetime.datetime.fromtimestamp(stat.st_mtime).strftime('%Y/%m/%d %H:%M:%S')}")
print(f"作成日時: {datetime.datetime.fromtimestamp(stat.st_ctime).strftime('%Y/%m/%d %H:%M:%S')}")
print(f"最終アクセス日時: {datetime.datetime.fromtimestamp(stat.st_atime).strftime('%Y/%m/%d %H:%M:%S')}")
print(f"所有者(UID): {stat.st_uid}")
print(f"グループ(GID): {stat.st_gid}")
print(f"パーミッション: {oct(stat.st_mode)}")
print(f"デバイスID: {stat.st_dev}")
print(f"ノードID(iノード): {stat.st_ino}")
print(f"ハードリンク数: {stat.st_nlink}")
from pathlib import Path
import datetime

# ファイルのパスを指定
file_path = 'C:/Windows/notepad.exe'

# pathlibモジュールを使用
stat = Path(file_path).stat()
print(f"ファイルサイズ: {stat.st_size} バイト")
print(f"最終更新日時: {datetime.datetime.fromtimestamp(stat.st_mtime).strftime('%Y/%m/%d %H:%M:%S')}")
print(f"作成日時: {datetime.datetime.fromtimestamp(stat.st_ctime).strftime('%Y/%m/%d %H:%M:%S')}")
print(f"最終アクセス日時: {datetime.datetime.fromtimestamp(stat.st_atime).strftime('%Y/%m/%d %H:%M:%S')}")
print(f"所有者(UID): {stat.st_uid}")
print(f"グループ(GID): {stat.st_gid}")
print(f"パーミッション: {oct(stat.st_mode)}")
print(f"デバイスID: {stat.st_dev}")
print(f"ノードID(iノード): {stat.st_ino}")
print(f"ハードリンク数: {stat.st_nlink}")

ファイルサイズ: 360448 バイト
最終更新日時: 2024/05/31 18:11:33
作成日時: 2024/05/31 18:11:33
最終アクセス日時: 2024/11/16 22:46:46
所有者(UID): 0
グループ(GID): 0
パーミッション: 0o100777
デバイスID: 133544273489860000
ノードID(iノード): 562949955076048
ハードリンク数: 3

os.stat_result クラスのプロパティは次の通りです。

プロパティプロパティ説明
ファイルサイズst_sizeファイルの場合はファイルサイズのバイト数。
フォルダの場合は常に0が返される。
最終更新日時st_mtimeファイルやフォルダの最終更新日時
(内容が変更された場合に更新)
作成日時st_ctimeファイルやフォルダの作成日時
(システムによる変更日時として扱われることが多い)
アクセス日時st_atimeファイルやフォルダの最終アクセス日時
ファイルの種類st_modeファイルやフォルダの種類をビットマスクで返します。S_IFDIRでフォルダであることを確認
所有者(UID)st_uidファイルやフォルダの所有者ユーザーID
グループ(GID)st_gidファイルやフォルダの所有者グループID
パーミッション(アクセス権)st_modeファイルやフォルダのパーミッション
(rwx形式などでアクセス権を確認)
デバイスIDst_devファイルやフォルダが存在するデバイスのID
ノードID(iノード)st_inoファイルやフォルダのiノードID
(ファイルシステム内での一意の識別子)
ハードリンク数st_nlinkファイルやフォルダのハードリンクの数(通常は2)

まとめ

この記事では、Pythonでフォルダやファイルのパス操作を行う際に便利なライブラリとして、従来のosモジュールと新しいpathlibモジュールの違いと使い方について詳しく説明しました。

また、それぞれのモジュールの特徴や利用シーンに応じた選び方を紹介し、具体的なコード例を通じて基本的な操作方法を示しました。

Pythonでパス操作を行う際には、プロジェクトの要件や好みに応じてosモジュールとpathlibモジュールを使い分けることができます。

osモジュールは歴史が長く、シンプルな操作に向いており、pathlibモジュールはオブジェクト指向的で、より直感的なコードを提供します。

それぞれの強みを活かして、効率的なパス操作を実装してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次