概要
この記事では、Pythonでディレクトリ(フォルダ)が存在するかどうかを確認する方法を解説します。ファイル操作を行う前にディレクトリの存在を確認することは、エラーを防ぎ、堅牢なプログラムを作成するために重要です。
Pythonでディレクトリが存在するかを確認する方法には、主にosモジュールとpathlibモジュールの2つがあります。
方法の比較
| メソッド | 用途 | 戻り値 | 推奨度 |
|---|---|---|---|
os.path.isdir() | ディレクトリのみ確認 | bool | ○ |
os.path.exists() | ファイル/ディレクトリ両方 | bool | △ |
Path.is_dir() | ディレクトリのみ確認 | bool | ◎(推奨) |
Path.exists() | ファイル/ディレクトリ両方 | bool | ○ |
Python 3.4以降では、pathlibモジュールの使用が推奨されます。
os.pathモジュールの使用
os.path.isdir() - ディレクトリ専用
os.path.isdir()を使うことで、特定のパスがディレクトリかどうかを確認できます。
import os
path = '/path/to/directory'
if os.path.isdir(path):
print("ディレクトリが存在します")
else:
print("ディレクトリが存在しません")
os.path.exists() - ファイルまたはディレクトリ
os.path.exists()は、ファイルかディレクトリのいずれかが存在するかを確認します。
import os
path = '/path/to/something'
if os.path.exists(path):
if os.path.isdir(path):
print("ディレクトリです")
else:
print("ファイルです")
else:
print("パスが存在しません")
各メソッドの挙動の違い
import os
# テスト用パス
dir_path = '/tmp/test_dir'
file_path = '/tmp/test_file.txt'
missing_path = '/tmp/not_exists'
# ディレクトリの場合
os.path.exists(dir_path) # True
os.path.isdir(dir_path) # True
os.path.isfile(dir_path) # False
# ファイルの場合
os.path.exists(file_path) # True
os.path.isdir(file_path) # False
os.path.isfile(file_path) # True
# 存在しない場合
os.path.exists(missing_path) # False
os.path.isdir(missing_path) # False
pathlibモジュールの使用
Python 3.4以降では、pathlibモジュールが導入され、オブジェクト指向的にファイルパスを操作できるようになりました。
基本的な使い方
from pathlib import Path
path = Path('/path/to/directory')
if path.is_dir():
print("ディレクトリが存在します")
else:
print("ディレクトリが存在しません")
パスの結合
pathlibでは/演算子でパスを結合できます。
from pathlib import Path
base_dir = Path('/home/user')
config_dir = base_dir / 'config' / 'myapp'
print(config_dir) # /home/user/config/myapp
print(config_dir.is_dir()) # True または False
ホームディレクトリの取得
from pathlib import Path
home = Path.home()
print(home) # /home/username (Linux) または C:\Users\username (Windows)
# ホーム配下のディレクトリを確認
downloads = home / 'Downloads'
if downloads.is_dir():
print(f"ダウンロードフォルダ: {downloads}")
ディレクトリの作成
ディレクトリが存在しない場合に作成する方法です。
os.makedirs()
import os
path = '/path/to/new/directory'
# exist_ok=True で既存ディレクトリでもエラーにならない
os.makedirs(path, exist_ok=True)
pathlib.Path.mkdir()
from pathlib import Path
path = Path('/path/to/new/directory')
# parents=True で親ディレクトリも作成
# exist_ok=True で既存でもエラーにならない
path.mkdir(parents=True, exist_ok=True)
確認してから作成するパターン
from pathlib import Path
def ensure_directory(path: str | Path) -> Path:
"""ディレクトリを確認し、存在しなければ作成する"""
dir_path = Path(path)
if not dir_path.exists():
dir_path.mkdir(parents=True)
print(f"ディレクトリを作成しました: {dir_path}")
elif not dir_path.is_dir():
raise ValueError(f"パスはファイルです: {dir_path}")
else:
print(f"ディレクトリは既に存在します: {dir_path}")
return dir_path
# 使用例
output_dir = ensure_directory('./output')
エラーハンドリング
権限エラーへの対処
from pathlib import Path
import os
def check_directory_safely(path: str) -> dict:
"""ディレクトリを安全に確認する"""
dir_path = Path(path)
result = {
'exists': False,
'is_dir': False,
'readable': False,
'writable': False,
'error': None
}
try:
result['exists'] = dir_path.exists()
result['is_dir'] = dir_path.is_dir()
if result['is_dir']:
# 読み取り権限の確認
result['readable'] = os.access(path, os.R_OK)
# 書き込み権限の確認
result['writable'] = os.access(path, os.W_OK)
except PermissionError as e:
result['error'] = f"権限エラー: {e}"
except OSError as e:
result['error'] = f"OSエラー: {e}"
return result
# 使用例
info = check_directory_safely('/etc')
print(info)
# {'exists': True, 'is_dir': True, 'readable': True, 'writable': False, 'error': None}
try-exceptを使ったディレクトリ作成
from pathlib import Path
def create_directory_safely(path: str) -> bool:
"""ディレクトリを安全に作成する"""
dir_path = Path(path)
try:
dir_path.mkdir(parents=True, exist_ok=True)
return True
except PermissionError:
print(f"権限がありません: {path}")
return False
except OSError as e:
print(f"ディレクトリ作成に失敗しました: {e}")
return False
# 使用例
if create_directory_safely('/tmp/myapp/logs'):
print("ディレクトリの準備完了")
クロスプラットフォーム対応
Windows、macOS、Linuxで動作するコードを書く場合の注意点です。
from pathlib import Path
import platform
def get_app_data_dir(app_name: str) -> Path:
"""OSに応じたアプリケーションデータディレクトリを取得"""
system = platform.system()
if system == 'Windows':
# Windows: C:\Users\<user>\AppData\Local\<app_name>
base = Path.home() / 'AppData' / 'Local'
elif system == 'Darwin':
# macOS: ~/Library/Application Support/<app_name>
base = Path.home() / 'Library' / 'Application Support'
else:
# Linux: ~/.local/share/<app_name>
base = Path.home() / '.local' / 'share'
app_dir = base / app_name
app_dir.mkdir(parents=True, exist_ok=True)
return app_dir
# 使用例
data_dir = get_app_data_dir('myapp')
print(f"データディレクトリ: {data_dir}")
実践例:設定ファイルディレクトリの管理
アプリケーションの設定ファイルを保存するディレクトリを管理する実践的な例です。
from pathlib import Path
import json
class ConfigManager:
"""設定ファイルを管理するクラス"""
def __init__(self, app_name: str):
self.app_name = app_name
self.config_dir = self._get_config_dir()
self.config_file = self.config_dir / 'settings.json'
def _get_config_dir(self) -> Path:
"""設定ディレクトリを取得し、存在しない場合は作成"""
config_dir = Path.home() / '.config' / self.app_name
if not config_dir.is_dir():
config_dir.mkdir(parents=True, exist_ok=True)
print(f"設定ディレクトリを作成: {config_dir}")
return config_dir
def load(self) -> dict:
"""設定を読み込む"""
if self.config_file.is_file():
with open(self.config_file, 'r', encoding='utf-8') as f:
return json.load(f)
return {}
def save(self, config: dict) -> None:
"""設定を保存する"""
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump(config, f, ensure_ascii=False, indent=2)
print(f"設定を保存: {self.config_file}")
# 使用例
if __name__ == "__main__":
config_manager = ConfigManager('myapp')
# 設定の読み込み
settings = config_manager.load()
# 設定の更新
settings['theme'] = 'dark'
settings['language'] = 'ja'
# 設定の保存
config_manager.save(settings)
まとめ
Pythonでディレクトリが存在するかどうかを確認する主な方法をまとめます。
| 状況 | 推奨メソッド |
|---|---|
| ディレクトリのみ確認 | Path.is_dir() |
| ファイルまたはディレクトリを確認 | Path.exists() |
| ディレクトリを作成 | Path.mkdir(parents=True, exist_ok=True) |
| 権限の確認 | os.access(path, os.R_OK) |
Python 3.4以降の環境では、より直感的で読みやすいpathlibの使用が推奨されます。os.pathモジュールは後方互換性のために残されていますが、新規コードではpathlibを優先して使用しましょう。