注目キーワード
  1. Python
  2. コンペ

Pythonでフォルダ作成を完全マスター!初心者でも分かるos.mkdir・makedirs・pathlibの使い分け

  • 2025年6月19日
  • 2025年6月19日
  • Python
  • 10回
  • 0件

「Pythonでプログラムを作っていて、ファイルを整理するためのフォルダを自動で作成したいけど、どの方法を使えばいいか分からない」

そんな悩みを持つ方に朗報です。実は、Pythonには複数のフォルダ作成方法があり、それぞれに特徴と適した使い場面があります。

この記事では、os.mkdir、os.makedirs、pathlibという3つの主要な方法を、初心者でも分かりやすく解説します。読み終わる頃には、どんな場面でどの方法を使えばよいか明確に理解でき、エラーハンドリングも含めた実用的なコードが書けるようになります。

Pythonでフォルダを作成する3つの方法

Pythonでフォルダ(ディレクトリ)を作成する方法は主に3つあります。それぞれの特徴を理解して、適切な場面で使い分けることが重要です。

os.mkdirを使った基本的なフォルダ作成

os.mkdirは最も基本的なフォルダ作成方法です。単一のフォルダを作成する際に使用します。

import os

# 基本的なフォルダ作成
os.mkdir('new_folder')

# 既存フォルダ内にサブフォルダ作成
os.mkdir('existing_folder/sub_folder')

ただし、os.mkdirには重要な制約があります。作成したいフォルダの親フォルダが存在していない場合、エラーが発生します。

import os

# これはエラーになる(parent_folderが存在しない場合)
try:
    os.mkdir('parent_folder/child_folder')
except FileNotFoundError as e:
    print(f"エラー: {e}")
    # エラー: [Errno 2] No such file or directory: 'parent_folder/child_folder'

os.makedirsで階層フォルダを一括作成

os.makedirsは階層になったフォルダを一括で作成できる便利な方法です。中間のフォルダが存在しなくても、自動的に作成してくれます。

import os

# 階層フォルダを一括作成
os.makedirs('project/data/raw')
os.makedirs('project/docs/images')

# 深い階層でも問題なし
os.makedirs('very/deep/folder/structure/example')

os.makedirsの最大の利点は、必要な中間フォルダを自動的に作成してくれることです。プロジェクトの初期設定時に複数のフォルダ構造を一度に作成する場合に特に有効です。

pathlibを使った現代的なフォルダ作成

Python 3.4以降で推奨されているpathlibモジュールを使用した方法です。オブジェクト指向的なアプローチでより直感的にフォルダ操作ができます。

from pathlib import Path

# 基本的なフォルダ作成
Path('new_folder').mkdir()

# 階層フォルダの作成(parents=Trueで中間フォルダも作成)
Path('project/data/processed').mkdir(parents=True)

# 既存フォルダでもエラーにならない設定
Path('existing_folder').mkdir(exist_ok=True)

pathlibは文字列ベースのパス操作よりも安全で読みやすいコードが書けるため、新しいプロジェクトでの使用が推奨されています。

os.mkdirとos.makedirsの違いと使い分け

os.mkdirとos.makedirsの具体的な違いを理解して、適切に使い分けましょう。

os.mkdirの特徴と制約

os.mkdirは単一のディレクトリのみを作成します。以下のような特徴があります:

制約:

  • 親ディレクトリが存在しない場合はエラー
  • 既に存在するディレクトリを指定するとエラー
  • 一度に一つのディレクトリしか作成できない

適用場面:

  • 既存のフォルダ内に新しいサブフォルダを作成する場合
  • シンプルなフォルダ作成で十分な場合
import os

# 正常なケース(親フォルダが存在する)
os.mkdir('documents')  # OK
os.mkdir('documents/reports')  # OK

# エラーケース
try:
    os.mkdir('non_existent/new_folder')  # FileNotFoundError
except FileNotFoundError:
    print("親フォルダが存在しません")

try:
    os.mkdir('documents')  # 既に存在する場合
except FileExistsError:
    print("フォルダは既に存在します")

os.makedirsの特徴と利点

os.makedirsは再帰的にディレクトリを作成し、必要な中間ディレクトリも自動的に作成します。

利点:

  • 深い階層のフォルダを一度に作成可能
  • 中間フォルダが存在しなくても自動作成
  • exist_okパラメータで既存フォルダのエラーを回避可能

適用場面:

  • プロジェクトの初期フォルダ構造作成
  • ログファイルの保存先フォルダ作成
  • データ処理パイプラインでの動的フォルダ作成
import os

# 複雑なフォルダ構造を一括作成
os.makedirs('project/src/utils', exist_ok=True)
os.makedirs('project/data/raw/2024/01', exist_ok=True)
os.makedirs('project/logs/error', exist_ok=True)

# exist_ok=Trueで既存フォルダでもエラー回避
os.makedirs('project/data/processed', exist_ok=True)

エラーハンドリングでトラブル回避

実際のプログラムでは、様々な理由でフォルダ作成が失敗する可能性があります。適切なエラーハンドリングを実装しましょう。

よくあるエラーとその対処法

フォルダ作成時によく発生するエラーとその対処法を紹介します。

1. FileExistsError(フォルダが既に存在)

import os

def create_folder_safe(folder_path):
    try:
        os.mkdir(folder_path)
        print(f"フォルダ '{folder_path}' を作成しました")
    except FileExistsError:
        print(f"フォルダ '{folder_path}' は既に存在します")
    except Exception as e:
        print(f"予期しないエラー: {e}")

create_folder_safe('test_folder')

2. FileNotFoundError(親フォルダが存在しない)

import os

def create_folder_with_parents(folder_path):
    try:
        os.mkdir(folder_path)
    except FileNotFoundError:
        print(f"親フォルダが存在しないため、makedirsを使用します")
        os.makedirs(folder_path, exist_ok=True)
    except FileExistsError:
        print(f"フォルダは既に存在します")

create_folder_with_parents('deep/nested/folder')

3. PermissionError(権限不足)

import os

def create_folder_with_permission_check(folder_path):
    try:
        os.makedirs(folder_path, exist_ok=True)
        print(f"フォルダ '{folder_path}' を作成しました")
    except PermissionError:
        print(f"フォルダ作成の権限がありません: {folder_path}")
    except Exception as e:
        print(f"エラーが発生しました: {e}")

create_folder_with_permission_check('/root/restricted_folder')

実用的なエラーハンドリングの実装

本格的なプログラムで使える、包括的なエラーハンドリング関数を作成しましょう。

import os
import logging
from pathlib import Path

def create_directory_robust(directory_path, use_pathlib=False):
    """
    堅牢なディレクトリ作成関数
    
    Args:
        directory_path (str): 作成するディレクトリのパス
        use_pathlib (bool): pathlibを使用するかどうか
    
    Returns:
        bool: 作成成功時はTrue、失敗時はFalse
    """
    try:
        if use_pathlib:
            Path(directory_path).mkdir(parents=True, exist_ok=True)
        else:
            os.makedirs(directory_path, exist_ok=True)
        
        logging.info(f"ディレクトリを作成しました: {directory_path}")
        return True
        
    except PermissionError:
        logging.error(f"権限エラー: {directory_path}")
        return False
    except OSError as e:
        logging.error(f"OS エラー: {e}")
        return False
    except Exception as e:
        logging.error(f"予期しないエラー: {e}")
        return False

# 使用例
logging.basicConfig(level=logging.INFO)

# 複数のディレクトリを安全に作成
directories = [
    'project/data/raw',
    'project/data/processed',
    'project/logs',
    'project/config'
]

for directory in directories:
    success = create_directory_robust(directory, use_pathlib=True)
    if not success:
        print(f"ディレクトリの作成に失敗: {directory}")

pathlibを使った現代的なディレクトリ管理

Python 3.4以降では、pathlibモジュールを使用したパス操作が推奨されています。より安全で読みやすいコードが書けます。

pathlibのメリットとos.pathとの違い

pathlibは従来のos.pathモジュールと比較して以下のメリットがあります:

pathlibのメリット:

  • オブジェクト指向的な設計で直感的
  • クロスプラットフォーム対応が自動的
  • メソッドチェーンによる処理の簡潔性
  • 型ヒントとの相性が良い

従来のos.pathとの比較:

import os
from pathlib import Path

# 従来の方法(os.path)
folder_path = os.path.join('project', 'data', 'raw')
if not os.path.exists(folder_path):
    os.makedirs(folder_path)

# pathlibを使った方法
folder_path = Path('project') / 'data' / 'raw'
folder_path.mkdir(parents=True, exist_ok=True)

pathlibでのフォルダ作成実践例

pathlibを使った実践的なフォルダ作成例を紹介します。

from pathlib import Path
from datetime import datetime

class ProjectFolderManager:
    """プロジェクトフォルダ管理クラス"""
    
    def __init__(self, project_name: str):
        self.project_root = Path(project_name)
    
    def create_standard_structure(self):
        """標準的なプロジェクト構造を作成"""
        folders = [
            self.project_root / 'src',
            self.project_root / 'data' / 'raw',
            self.project_root / 'data' / 'processed',
            self.project_root / 'docs',
            self.project_root / 'tests',
            self.project_root / 'logs',
            self.project_root / 'config'
        ]
        
        for folder in folders:
            folder.mkdir(parents=True, exist_ok=True)
            print(f"作成完了: {folder}")
    
    def create_dated_folder(self, base_folder: str = 'data'):
        """日付ベースのフォルダを作成"""
        today = datetime.now().strftime('%Y-%m-%d')
        dated_folder = self.project_root / base_folder / today
        dated_folder.mkdir(parents=True, exist_ok=True)
        return dated_folder

# 使用例
manager = ProjectFolderManager('my_data_analysis')
manager.create_standard_structure()

# 今日の日付フォルダを作成
today_folder = manager.create_dated_folder()
print(f"今日のデータフォルダ: {today_folder}")

権限設定付きフォルダ作成:

from pathlib import Path
import stat

def create_folder_with_permissions(folder_path: str, permissions: int = 0o755):
    """
    権限を指定してフォルダを作成
    
    Args:
        folder_path: フォルダパス
        permissions: 8進数での権限指定(デフォルト: 0o755)
    """
    folder = Path(folder_path)
    folder.mkdir(parents=True, exist_ok=True)
    folder.chmod(permissions)
    
    # 権限確認
    current_permissions = oct(folder.stat().st_mode)[-3:]
    print(f"フォルダ '{folder_path}' を権限 {current_permissions} で作成")

# 使用例
create_folder_with_permissions('secure_data', 0o700)  # 所有者のみアクセス可能
create_folder_with_permissions('shared_data', 0o755)  # 標準権限

実用的なフォルダ作成のコード例

実際のプロジェクトで使える実用的なフォルダ作成のコード例を紹介します。

プロジェクト用フォルダ構造の自動作成

データサイエンスプロジェクトでよく使われるフォルダ構造を自動作成するスクリプトです。

from pathlib import Path
import json
from datetime import datetime

def create_data_science_project(project_name: str, config_file: str = None):
    """
    データサイエンスプロジェクト用のフォルダ構造を作成
    
    Args:
        project_name: プロジェクト名
        config_file: 設定ファイルのパス(JSON形式)
    """
    
    # デフォルトのフォルダ構造
    default_structure = {
        "folders": [
            "data/raw",
            "data/interim",
            "data/processed",
            "data/external",
            "notebooks/exploratory",
            "notebooks/reports",
            "src/data",
            "src/features",
            "src/models",
            "src/visualization",
            "models/trained",
            "models/serialized",
            "references",
            "reports/figures",
            "reports/presentations",
            "tests",
            "logs",
            "config"
        ]
    }
    
    # 設定ファイルがある場合は読み込み
    if config_file and Path(config_file).exists():
        with open(config_file, 'r', encoding='utf-8') as f:
            structure = json.load(f)
    else:
        structure = default_structure
    
    # プロジェクトルートフォルダ作成
    project_root = Path(project_name)
    project_root.mkdir(exist_ok=True)
    
    # フォルダ構造作成
    created_folders = []
    for folder in structure['folders']:
        folder_path = project_root / folder
        folder_path.mkdir(parents=True, exist_ok=True)
        created_folders.append(str(folder_path))
    
    print(f"プロジェクト '{project_name}' を作成しました")
    print(f"作成されたフォルダ数: {len(created_folders)}")
    
    return project_root, created_folders

# 使用例
project_root, folders = create_data_science_project('sales_analysis_2024')

日付フォルダの自動生成

ログファイルやバックアップファイルの整理に便利な日付ベースのフォルダ自動生成機能です。

from pathlib import Path
from datetime import datetime, timedelta
import calendar

class DateFolderManager:
    """日付ベースのフォルダ管理クラス"""
    
    def __init__(self, base_path: str = "data"):
        self.base_path = Path(base_path)
        self.base_path.mkdir(exist_ok=True)
    
    def create_daily_folder(self, date: datetime = None) -> Path:
        """日付フォルダを作成(YYYY/MM/DD形式)"""
        if date is None:
            date = datetime.now()
        
        folder_path = self.base_path / str(date.year) / f"{date.month:02d}" / f"{date.day:02d}"
        folder_path.mkdir(parents=True, exist_ok=True)
        return folder_path
    
    def create_monthly_folders(self, year: int = None) -> list:
        """指定年の月別フォルダを作成"""
        if year is None:
            year = datetime.now().year
        
        monthly_folders = []
        for month in range(1, 13):
            month_name = calendar.month_name[month]
            folder_path = self.base_path / str(year) / f"{month:02d}_{month_name}"
            folder_path.mkdir(parents=True, exist_ok=True)
            monthly_folders.append(folder_path)
        
        return monthly_folders
    
    def create_backup_structure(self, retention_days: int = 30):
        """バックアップ用の日付フォルダ構造を作成"""
        backup_folders = []
        today = datetime.now()
        
        for i in range(retention_days):
            backup_date = today - timedelta(days=i)
            folder_path = self.create_daily_folder(backup_date)
            backup_folders.append(folder_path)
        
        print(f"{retention_days}日分のバックアップフォルダを作成しました")
        return backup_folders

# 使用例
date_manager = DateFolderManager("logs")

# 今日のログフォルダ作成
today_folder = date_manager.create_daily_folder()
print(f"今日のログフォルダ: {today_folder}")

# 2024年の月別フォルダ作成
monthly_folders = date_manager.create_monthly_folders(2024)
print(f"月別フォルダを{len(monthly_folders)}個作成")

# 30日分のバックアップフォルダ作成
backup_folders = date_manager.create_backup_structure(30)

ログファイル管理の実践例:

from pathlib import Path
from datetime import datetime
import logging

class LogFolderManager:
    """ログファイル用フォルダ管理クラス"""
    
    def __init__(self, base_log_dir: str = "logs"):
        self.base_log_dir = Path(base_log_dir)
    
    def setup_logging_folders(self, app_name: str):
        """アプリケーション用のログフォルダ構造を作成"""
        today = datetime.now()
        
        # ログフォルダ構造: logs/app_name/YYYY/MM/DD/
        log_structure = {
            'daily': self.base_log_dir / app_name / str(today.year) / f"{today.month:02d}" / f"{today.day:02d}",
            'error': self.base_log_dir / app_name / 'errors' / str(today.year),
            'debug': self.base_log_dir / app_name / 'debug' / str(today.year),
            'access': self.base_log_dir / app_name / 'access' / str(today.year)
        }
        
        created_folders = {}
        for log_type, folder_path in log_structure.items():
            folder_path.mkdir(parents=True, exist_ok=True)
            created_folders[log_type] = folder_path
        
        return created_folders
    
    def get_log_file_path(self, app_name: str, log_type: str = 'daily'):
        """ログファイルパスを取得"""
        folders = self.setup_logging_folders(app_name)
        today = datetime.now()
        
        if log_type == 'daily':
            filename = f"{app_name}_{today.strftime('%Y%m%d')}.log"
        else:
            filename = f"{app_name}_{log_type}_{today.strftime('%Y%m%d')}.log"
        
        return folders[log_type] / filename

# 使用例
log_manager = LogFolderManager()

# Webアプリケーション用ログフォルダ作成
web_log_folders = log_manager.setup_logging_folders('web_app')
print("Webアプリ用ログフォルダ作成完了:")
for log_type, folder in web_log_folders.items():
    print(f"  {log_type}: {folder}")

# ログファイルパス取得
error_log_path = log_manager.get_log_file_path('web_app', 'error')
print(f"エラーログファイル: {error_log_path}")

まとめ

この記事では、Pythonでフォルダを作成する3つの主要な方法について詳しく解説しました。

重要なポイント:

  • os.mkdir: 単一フォルダの作成に適している。親フォルダが必要
  • os.makedirs: 階層フォルダの一括作成が可能。exist_okで安全性向上
  • pathlib: 現代的でオブジェクト指向的なアプローチ。推奨方法

選択の指針:

  • 新しいプロジェクトではpathlibを使用する
  • 階層フォルダが必要な場合はos.makedirsまたはpathlib.mkdir(parents=True)を使用
  • エラーハンドリングを必ず実装する
  • exist_okパラメータを活用してエラーを回避

これらの知識を活用して、効率的で堅牢なPythonプログラムを作成してください。フォルダ作成は多くのプロジェクトで必要となる基本的な操作ですが、適切な方法を選択することで、より安全で保守性の高いコードが書けるようになります。

特に実際のプロジェクトでは、エラーハンドリングと組み合わせたフォルダ作成機能を実装することで、予期しない問題を回避し、安定したプログラムを構築できます。

最新情報をチェックしよう!