【初心者向け】Pythonでのファイル操作を完全マスター!読み書き・便利技までやさしく解説

python

「pythonでファイルを読み書きしたい」
「データを保存して後から使いたい」
「CSVファイルやテキストファイルを扱いたい」

そんな疑問を解決するために、今回はpythonでのファイル操作について、初心者の方でも理解できるように詳しく説明していきます。

スポンサーリンク

ファイル操作の基本概念

まず、pythonでのファイル操作の基本的な考え方を理解しましょう。

ファイル操作の3つの基本ステップ

1. ファイルを開く(open)
2. ファイルに対して操作する(読み込み・書き込み)
3. ファイルを閉じる(close)

ファイルモードの種類

モード意味用途
"r"読み込み専用ファイルの内容を読み取る
"w"書き込み専用新しくファイルを作成または上書き
"a"追記専用既存ファイルの末尾に追加
"x"排他的作成ファイルが存在しない場合のみ作成
"r+"読み書き両用既存ファイルの読み書き

ファイルを開いて読み込む方法

基本的な読み込み

pythonでファイルを読み込む最も基本的な方法です。

# 基本的なファイル読み込み
with open("sample.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)

重要なポイント:

  • with文を使うことで、自動的にファイルが閉じられる
  • encoding="utf-8"で文字化けを防ぐ
  • f.read()でファイル全体を一度に読み込み

行ごとに読み込む方法

大きなファイルを扱う場合や、行ごとに処理したい場合に便利です。

# 行ごとに読み込み
with open("sample.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.strip())  # .strip()で改行を除去

より詳細な読み込み方法

# 方法1:すべての行をリストとして取得
with open("sample.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()
    print(lines)  # ['1行目\n', '2行目\n', '3行目\n']

# 方法2:1行ずつ読み込み
with open("sample.txt", "r", encoding="utf-8") as f:
    first_line = f.readline()
    print(first_line.strip())

# 方法3:指定した文字数だけ読み込み
with open("sample.txt", "r", encoding="utf-8") as f:
    chunk = f.read(10)  # 最初の10文字だけ読み込み
    print(chunk)

読み込み時の実用例

# 設定ファイルの読み込み例
def read_config(filename):
    """設定ファイルを読み込んで辞書で返す"""
    config = {}
    try:
        with open(filename, "r", encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith("#"):  # 空行とコメント行を除外
                    key, value = line.split("=", 1)
                    config[key.strip()] = value.strip()
    except FileNotFoundError:
        print(f"設定ファイル {filename} が見つかりません")
    
    return config

# 使用例
settings = read_config("config.txt")
print(settings)

ファイルへの書き込み・追記方法

新規作成・上書き書き込み(”w”モード)

# 新しいファイルを作成または既存ファイルを上書き
with open("output.txt", "w", encoding="utf-8") as f:
    f.write("これは新しいファイルです。\n")
    f.write("2行目の内容です。\n")

print("ファイルを作成しました")

注意点:

  • "w"モードは既存ファイルの内容を完全に消去します
  • ファイルが存在しない場合は新規作成されます

追記書き込み(”a”モード)

# 既存ファイルの末尾に追加
with open("output.txt", "a", encoding="utf-8") as f:
    f.write("この行は追加されます。\n")
    f.write("さらにもう1行追加。\n")

print("内容を追加しました")

複数行の一括書き込み

# リストの内容を一括で書き込み
fruits = ["りんご", "バナナ", "みかん", "ぶどう"]

# 方法1:writelines()を使用
with open("fruits.txt", "w", encoding="utf-8") as f:
    f.writelines([fruit + "\n" for fruit in fruits])

# 方法2:joinを使用
with open("fruits2.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(fruits) + "\n")

# 方法3:forループを使用
with open("fruits3.txt", "w", encoding="utf-8") as f:
    for fruit in fruits:
        f.write(fruit + "\n")

実用的な書き込み例

import datetime

def write_log(message, filename="app.log"):
    """ログファイルにタイムスタンプ付きでメッセージを記録"""
    timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    with open(filename, "a", encoding="utf-8") as f:
        f.write(f"[{timestamp}] {message}\n")

# 使用例
write_log("アプリケーションを開始しました")
write_log("データ処理を実行中")
write_log("処理が完了しました")

ファイル操作の便利なテクニック

ファイルの存在確認

import os

# 方法1:os.path.exists()を使用
if os.path.exists("sample.txt"):
    print("ファイルが存在します")
else:
    print("ファイルが見つかりません")

# 方法2:pathlib を使用(Python 3.4以降)
from pathlib import Path

file_path = Path("sample.txt")
if file_path.exists():
    print("ファイルが存在します")
    print(f"ファイルサイズ: {file_path.stat().st_size} bytes")
else:
    print("ファイルが見つかりません")

ファイル情報の取得

import os
from pathlib import Path
import datetime

def get_file_info(filename):
    """ファイルの詳細情報を取得"""
    if not os.path.exists(filename):
        return "ファイルが存在しません"
    
    stat = os.stat(filename)
    
    info = {
        "サイズ": stat.st_size,
        "作成日時": datetime.datetime.fromtimestamp(stat.st_ctime),
        "更新日時": datetime.datetime.fromtimestamp(stat.st_mtime),
        "アクセス日時": datetime.datetime.fromtimestamp(stat.st_atime)
    }
    
    return info

# 使用例
file_info = get_file_info("sample.txt")
for key, value in file_info.items():
    print(f"{key}: {value}")

ディレクトリ操作

import os
from pathlib import Path

# ディレクトリの作成
os.makedirs("new_directory", exist_ok=True)  # exist_ok=Trueで既存時エラー回避

# ディレクトリ内のファイル一覧
files = os.listdir(".")  # 現在のディレクトリ
print("ファイル一覧:", files)

# pathlib を使った方法(推奨)
current_dir = Path(".")
txt_files = list(current_dir.glob("*.txt"))  # .txtファイルのみ
print("テキストファイル:", txt_files)

# ディレクトリの削除(空の場合)
# os.rmdir("empty_directory")

ファイルのコピー・移動・削除

import shutil
import os

# ファイルのコピー
shutil.copy2("source.txt", "backup.txt")  # copy2はメタデータも保持

# ファイルの移動
shutil.move("old_location.txt", "new_location.txt")

# ファイルの削除
if os.path.exists("temp_file.txt"):
    os.remove("temp_file.txt")
    print("ファイルを削除しました")

# ディレクトリごと削除
# shutil.rmtree("directory_to_delete")  # 注意:中身ごと削除される

エラー処理とトラブルシューティング

FileNotFoundError

# エラーが起きる例
try:
    with open("存在しないファイル.txt", "r") as f:
        content = f.read()
except FileNotFoundError:
    print("ファイルが見つかりません")

# 安全な方法
def safe_read_file(filename):
    """安全にファイルを読み込む"""
    try:
        with open(filename, "r", encoding="utf-8") as f:
            return f.read()
    except FileNotFoundError:
        print(f"ファイル '{filename}' が見つかりません")
        return None
    except PermissionError:
        print(f"ファイル '{filename}' にアクセス権限がありません")
        return None
    except Exception as e:
        print(f"予期しないエラーが発生しました: {e}")
        return None

# 使用例
content = safe_read_file("sample.txt")
if content is not None:
    print(content)

UnicodeDecodeError(文字化け)

# 文字エンコーディングの問題を解決
def read_file_with_encoding(filename, encodings=["utf-8", "shift_jis", "cp932"]):
    """複数のエンコーディングを試してファイルを読み込む"""
    for encoding in encodings:
        try:
            with open(filename, "r", encoding=encoding) as f:
                content = f.read()
                print(f"エンコーディング '{encoding}' で読み込み成功")
                return content
        except UnicodeDecodeError:
            continue
        except FileNotFoundError:
            print(f"ファイル '{filename}' が見つかりません")
            return None
    
    print("どのエンコーディングでも読み込めませんでした")
    return None

# 使用例
content = read_file_with_encoding("japanese_file.txt")

PermissionError

# 権限エラーの対処
import os
import stat

def make_writable(filename):
    """ファイルを書き込み可能にする"""
    try:
        # ファイルの権限を変更
        os.chmod(filename, stat.S_IWRITE | stat.S_IREAD)
        print(f"{filename} を書き込み可能にしました")
    except Exception as e:
        print(f"権限変更に失敗: {e}")

# 使用例
make_writable("readonly_file.txt")

CSVファイルの操作

CSVファイルの読み込み

import csv

# 基本的なCSV読み込み
def read_csv_file(filename):
    """CSVファイルを読み込んでリストで返す"""
    data = []
    try:
        with open(filename, "r", encoding="utf-8") as f:
            reader = csv.reader(f)
            headers = next(reader)  # ヘッダー行を取得
            print(f"ヘッダー: {headers}")
            
            for row in reader:
                data.append(row)
    except FileNotFoundError:
        print(f"ファイル {filename} が見つかりません")
    
    return data

# 辞書形式でCSV読み込み
def read_csv_as_dict(filename):
    """CSVファイルを辞書のリストとして読み込む"""
    data = []
    try:
        with open(filename, "r", encoding="utf-8") as f:
            reader = csv.DictReader(f)
            for row in reader:
                data.append(dict(row))
    except FileNotFoundError:
        print(f"ファイル {filename} が見つかりません")
    
    return data

# 使用例
csv_data = read_csv_as_dict("data.csv")
for row in csv_data:
    print(row)

CSVファイルの書き込み

import csv

def write_csv_file(filename, data, headers=None):
    """データをCSVファイルに書き込む"""
    try:
        with open(filename, "w", newline="", encoding="utf-8") as f:
            writer = csv.writer(f)
            
            # ヘッダーがある場合は先に書き込み
            if headers:
                writer.writerow(headers)
            
            # データを書き込み
            for row in data:
                writer.writerow(row)
        
        print(f"CSVファイル {filename} を作成しました")
    except Exception as e:
        print(f"CSVファイル書き込みエラー: {e}")

# 使用例
headers = ["名前", "年齢", "職業"]
data = [
    ["田中太郎", 30, "エンジニア"],
    ["佐藤花子", 25, "デザイナー"],
    ["山田次郎", 35, "営業"]
]

write_csv_file("employees.csv", data, headers)

JSONファイルの操作

JSONファイルの読み書き

import json

def read_json_file(filename):
    """JSONファイルを読み込んで辞書で返す"""
    try:
        with open(filename, "r", encoding="utf-8") as f:
            data = json.load(f)
        return data
    except FileNotFoundError:
        print(f"ファイル {filename} が見つかりません")
        return {}
    except json.JSONDecodeError as e:
        print(f"JSON形式エラー: {e}")
        return {}

def write_json_file(filename, data):
    """辞書データをJSONファイルに書き込む"""
    try:
        with open(filename, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        print(f"JSONファイル {filename} を作成しました")
    except Exception as e:
        print(f"JSONファイル書き込みエラー: {e}")

# 使用例
user_data = {
    "name": "田中太郎",
    "age": 30,
    "hobbies": ["読書", "映画鑑賞", "プログラミング"],
    "address": {
        "prefecture": "東京都",
        "city": "渋谷区"
    }
}

write_json_file("user.json", user_data)
loaded_data = read_json_file("user.json")
print(loaded_data)

実践的な活用例

ログファイルの管理

import datetime
import os

class Logger:
    def __init__(self, log_file="app.log", max_size=1024*1024):  # 1MB
        self.log_file = log_file
        self.max_size = max_size
    
    def _rotate_log(self):
        """ログファイルのローテーション"""
        if os.path.exists(self.log_file) and os.path.getsize(self.log_file) > self.max_size:
            backup_name = f"{self.log_file}.old"
            if os.path.exists(backup_name):
                os.remove(backup_name)
            os.rename(self.log_file, backup_name)
    
    def log(self, level, message):
        """ログを出力"""
        self._rotate_log()
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = f"[{timestamp}] {level}: {message}\n"
        
        with open(self.log_file, "a", encoding="utf-8") as f:
            f.write(log_entry)
    
    def info(self, message):
        self.log("INFO", message)
    
    def error(self, message):
        self.log("ERROR", message)
    
    def warning(self, message):
        self.log("WARNING", message)

# 使用例
logger = Logger()
logger.info("アプリケーション開始")
logger.warning("メモリ使用量が80%を超えました")
logger.error("データベース接続エラー")

設定ファイルの管理

import json
import os

class ConfigManager:
    def __init__(self, config_file="config.json"):
        self.config_file = config_file
        self.default_config = {
            "database": {
                "host": "localhost",
                "port": 5432,
                "name": "myapp"
            },
            "logging": {
                "level": "INFO",
                "file": "app.log"
            },
            "app": {
                "debug": False,
                "secret_key": "your-secret-key"
            }
        }
        self.config = self.load_config()
    
    def load_config(self):
        """設定ファイルを読み込み"""
        if os.path.exists(self.config_file):
            try:
                with open(self.config_file, "r", encoding="utf-8") as f:
                    return json.load(f)
            except (json.JSONDecodeError, FileNotFoundError):
                print("設定ファイルの読み込みに失敗。デフォルト設定を使用します。")
        
        # デフォルト設定を保存
        self.save_config(self.default_config)
        return self.default_config.copy()
    
    def save_config(self, config=None):
        """設定ファイルを保存"""
        if config is None:
            config = self.config
        
        try:
            with open(self.config_file, "w", encoding="utf-8") as f:
                json.dump(config, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"設定ファイルの保存に失敗: {e}")
    
    def get(self, key, default=None):
        """設定値を取得"""
        keys = key.split(".")
        value = self.config
        for k in keys:
            value = value.get(k, default)
            if value is None:
                return default
        return value
    
    def set(self, key, value):
        """設定値を更新"""
        keys = key.split(".")
        config = self.config
        for k in keys[:-1]:
            if k not in config:
                config[k] = {}
            config = config[k]
        config[keys[-1]] = value
        self.save_config()

# 使用例
config = ConfigManager()
print(config.get("database.host"))  # localhost
config.set("app.debug", True)
print(config.get("app.debug"))  # True

よくある疑問

Q
大きなファイルを扱う時に注意することは?
A

メモリ不足を防ぐため、一度にすべてを読み込まず、行ごとやチャンクごとに処理しましょう。

# 大きなファイルの処理例
def process_large_file(filename, chunk_size=1024):
    with open(filename, "r", encoding="utf-8") as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            # チャンクごとに処理
            process_chunk(chunk)
Q
バイナリファイル(画像など)を扱いたい場合は?
A

モードに"b"を追加して(例:"rb""wb")バイナリモードで開いてください。

まとめ

pythonでのファイル操作は、プログラミングの基本中の基本でありながら、実務でも非常に重要なスキルです。

おさらい:

  • 基本操作with open()文を使った安全なファイル操作
  • 読み込みread()readline()readlines()の使い分け
  • 書き込み"w"(上書き)と"a"(追記)モードの違い
  • エラー処理:try-except文を使った堅牢なコード
  • 実践応用:CSV、JSON、ログファイルの操作

コメント

タイトルとURLをコピーしました