Python | ファイル操作など:write

Python
スポンサーリンク

概要(write は「ファイルに内容を書き込む」ための基本メソッド)

write は、open で開いたファイルオブジェクトに文字列(テキスト)または bytes(バイナリ)を書き込むメソッドです。テキストは “w”(上書き)や “a”(追記)で、バイナリは “wb” や “ab” を使います。重要なのはモード選択、encoding の明示、改行の扱い、そして with 文で「自動クローズ」する習慣です。

# テキスト上書き(UTF-8)
with open("out.txt", "w", encoding="utf-8") as f:
    f.write("こんにちは\n")
Python

基本の使い方とモード(ここが重要)

上書き・追記・新規作成の違い

“w” はファイルを新規作成または中身を消してから書き込みます。”a” は既存の末尾に追記します。”x” は存在しないときだけ新規作成し、既存ならエラーで安全に守ります。誤上書きの防止が必要な成果物では “x” が有効です。

# 追記(末尾に行を追加)
with open("log.txt", "a", encoding="utf-8") as f:
    f.write("started\n")
Python

テキストとバイナリで引数が変わる

テキストは文字列を書きます(encoding を明示)。画像や圧縮などのバイナリは bytes を書きます。間違えると文字化けやファイル破損につながるため、対象に合わせて “t”/”b” を使い分けます。

# バイナリコピー
with open("in.png", "rb") as src, open("out.png", "wb") as dst:
    dst.write(src.read())
Python

with 文でクローズを自動化し、例外でも安全に

ファイルは必ず閉じる必要があります。with 文なら例外が起きても自動で close され、リソースリークや書き込み漏れを防げます。これは厳守の基本ルールです。

with open("data.csv", "w", encoding="utf-8") as f:
    f.write("name,qty\ncoffee,2\n")
Python

改行・エンコーディング・バッファ(重要ポイントの深掘り)

改行は自動で入らない(”\n” を明示)

write は渡した文字列をそのまま書きます。行ごとに書くときは末尾に必ず “\n” を付けます。プラットフォーム差を均一化したいなら、テキストモードで newline=”\n” を指定すると入出力が揃います。

with open("log.txt", "w", encoding="utf-8", newline="\n") as f:
    f.write("OK\n")
Python

encoding は原則 UTF-8 を明示

環境依存の既定エンコーディングは事故のもとです。日本語を扱うテキストは “utf-8″ を毎回指定しましょう。どうしても外部要因で文字化けする場合は errors 引数で挙動を選べます(例:errors=”ignore” は非推奨、”replace” は応急処置)。

with open("jp.txt", "w", encoding="utf-8") as f:
    f.write("コーヒー\n")
Python

バッファと flush(すぐ保存したいとき)

書き込みは一度バッファに溜まります。今すぐディスクへ反映したいなら f.flush()、または print(…, flush=True) を使います。ただし頻繁な flush は性能低下を招くため、必要時のみ。

with open("progress.txt", "w", encoding="utf-8") as f:
    f.write("step1\n")
    f.flush()  # ここで即保存
Python

write の挙動と関連メソッド(戻り値・writelines・print)

戻り値は「書いた文字数(またはバイト数)」

write は実際に書いた長さ(int)を返します。必要なら検証に使えますが、通常は戻り値を使用せず「例外がなければ成功」と読んで問題ありません。

with open("count.txt", "w", encoding="utf-8") as f:
    n = f.write("hello\n")
    # n == 6("hello" + 改行)
Python

複数行の一括書き込みは writelines

writelines は「文字列の反復可能」を受け取り、連続で書きます。改行は自動で付かないため、各要素に “\n” を付けるか、生成式で付けて渡します。

rows = ["a,1", "b,2", "c,3"]
with open("out.csv", "w", encoding="utf-8") as f:
    f.writelines(r + "\n" for r in rows)
Python

print の file 引数で「改行付きで簡便に書く」

print は既定で末尾に改行を付けます。file 引数にファイルオブジェクトを渡せば、ログ風の書き込みが簡潔になります。sep や end で整形も自在です。

with open("app.log", "a", encoding="utf-8") as f:
    print("INFO", "started", file=f)         # "INFO started\n"
    print("OK", end="\n\n", file=f)          # 空行を1つ追加
Python

安全設計(誤上書き対策・一時ファイル・例外処理)

誤上書きを避ける基本線

重要なファイルは “x” モード(新規のみ)で生成し、既存なら FileExistsError を出してユーザーに確認を促します。レポートや成果物の保全に有効です。

try:
    with open("report.txt", "x", encoding="utf-8") as f:
        f.write("new report\n")
except FileExistsError:
    print("既に存在します")
Python

原子的な書き込み(テンポラリ→置き換え)

「途中で落ちても壊れないように」一時ファイルへ書いてから置き換えるのが定石です。pathlib でパス操作、os.replace でアトミックに差し替えます。

import os
from pathlib import Path

def atomic_write(path: str, data: str) -> None:
    p = Path(path)
    tmp = p.with_suffix(p.suffix + ".tmp")
    with tmp.open("w", encoding="utf-8", newline="\n") as f:
        f.write(data)
        f.flush()
        os.fsync(f.fileno())  # OSのバッファも同期(重要)
    os.replace(tmp, p)  # 原子的に置き換え
Python

例外ハンドリング(PermissionError・ディレクトリ作成)

書き込み先ディレクトリがなければ作成してから開く、権限エラーはメッセージを出すなど、外部要因を想定した防御を入れましょう。

from pathlib import Path

def save_text(path: str, text: str) -> bool:
    p = Path(path)
    p.parent.mkdir(parents=True, exist_ok=True)
    try:
        p.write_text(text, encoding="utf-8")
        return True
    except PermissionError:
        return False
Python

例題で身につける(定番から一歩先まで)

例題1:CSV を安全に書き出す(改行統一)

rows = [["name", "qty"], ["coffee", 2], ["tea", 1]]
with open("stock.csv", "w", encoding="utf-8", newline="\n") as f:
    for r in rows:
        f.write(",".join(map(str, r)) + "\n")
Python

例題2:ログ追記を print で簡潔に

def log(msg: str) -> None:
    with open("app.log", "a", encoding="utf-8") as f:
        print("INFO", msg, file=f)

log("started")
log("done")
Python

例題3:JSON の保存(UTF-8・整形)

import json

data = {"items": ["coffee", "tea"], "qty": 3}
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)
Python

例題4:バイナリ書き込みで簡易ダンプ

payload = b"\x00\x01\x02\x03"
with open("dump.bin", "wb") as f:
    f.write(payload)
Python

まとめ

write は「何を、どのモードで、どう整形して」書くかの選択が肝心です。テキストは UTF-8 と改行の明示、バイナリは bytes で “wb” を徹底。with 文で自動クローズ、必要時のみ flush。誤上書きには “x”、重要ファイルは原子的な置き換えで守る。複数行は writelines、ログには print(file=…) が簡潔。これらを守るだけで、初心者のファイル書き込みは安定し、実務で通用する品質に一気に近づきます。

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