Documentation Python

概要

この記事では、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を優先して使用しましょう。

参考文献

円