Yomiage
メニュー

Python実践講座 06:例外と後始末を設計する

更新 2026/9/27 6:22:11 公開

投稿者: しゅりりん

到達点は、想定内の入力エラーと予期しない不具合を分けることです。前提は第05回です。

捕まえる範囲を狭くする

tryには失敗する可能性のある操作を置き、exceptには対処を置きます。どんな例外でも成功扱いにすると、プログラムの間違いまで隠します。数値変換ならValueError、ファイルがないならFileNotFoundErrorなど、対処できる種類を選びます。

from io import StringIO


def parse_minutes(text: str) -> int:
    try:
        value = int(text)
    except ValueError as exc:
        raise ValueError("学習時間は整数で指定します") from exc
    if value < 0:
        raise ValueError("学習時間は0以上です")
    return value


with StringIO("25\nabc\n-1\n") as source:
    for line in source:
        try:
            print(parse_minutes(line.strip()))
        except ValueError as exc:
            print(f"入力エラー: {exc}")
print(source.closed)

main.pyで実行すると25、形式エラー、範囲エラー、最後にTrueが表示されます。withを抜けると後始末され、例外で途中終了した場合にも閉じる処理が行われます。fromを使って変換前の原因を残すと、調査時に経緯を追えます。

例外はどこで利用者向けに変えるか

深い関数でエラーを表示してNoneを返すより、例外を上位へ伝え、CLIや画面の入口で利用者向けの表示に変える方法があります。失敗した場合の戻り値を常に確認し忘れないようにする効果もあります。

finallyは成功・失敗に関係なく必要な後始末に使います。ただしfinallyの中でreturnすると、元の例外や戻り値を覆い隠すことがあります。リソースの管理には、使えるならwithを選びます。

except: はKeyboardInterruptやSystemExitまで捕まえます。終了操作を妨げないよう、通常は具体的な例外を指定します。またassertはデバッグ上の前提確認に使い、利用者の入力検証には使いません。最適化オプションでassertが省略される場合があるためです。

練習と解答

練習:不正な行を読み飛ばして合計する仕様と、一行でも不正なら全体を失敗にする仕様を比較します。

解答:前者はループ内で捕まえて行番号を記録し、後者は外側まで例外を伝えます。売上など欠落が困るデータでは、読み飛ばしを成功として扱わない設計が必要です。どちらが正しいかはデータの用途で決まります。

公式資料

例外処理が参照先です。


Python全20回の目次 | 前の回 | 次の回

このブラウザでは Web Speech API が利用できません。

1 / 16 · 停止中