MENU

Python例外処理の基本|止まらない自動化にするtry/except

当ページのリンクには広告(PR)が含まれていることがあります。
Python例外処理の基本|止まらない自動化にするtry/exceptのアイキャッチ

一行の入力ミスで全体が止まると、残りのどこまで処理できたか分からなくなります。ただ、exceptで何でも無視すると、失敗した分まで成功したように見えます。続けられる不備と、結果を確定する前に止める条件を分けます。

目次

exceptを置く範囲

tryの中で例外が起きると、その後の処理は飛ばされ、種類が合うexceptへ移ります。ファイルを開く、数値へ変換する、結果を保存する処理を全部まとめて囲むと、どの失敗を想定したのか読み取りにくくなります。

入力値を数へ変えるときのValueErrorと、ファイルがないときのFileNotFoundErrorは、確認先が違います。原因を区別したい場所ごとに、受け取る例外を決めます。

不備を記録して最後に判断する例

次は架空の金額三件を調べる例です。すべての入力を確認しますが、不備があれば合計を完成結果として出さず、終了コード1で止めます。

raw_values = ["1200", "-5", ""]
amounts = []
errors = []
for row_number, raw in enumerate(raw_values, start=1):
    try:
        amount = int(raw)
        if amount < 0:
            raise ValueError("負数は対象外です")
    except ValueError:
        errors.append(row_number)
    else:
        amounts.append(amount)

print(f"有効{len(amounts)}件・要確認{len(errors)}件")
if errors:
    print("要確認の行:", errors)
    raise SystemExit(1)
print("合計:", sum(amounts))

この入力では有効1件・要確認2件となり、2行目と3行目を確認するために停止します。負数を対象外にするのは、この例の入力ルールです。返品を負数で扱う業務なら、その条件を変更します。

入力ミスを0として足す処理にはしていません。途中まで計算できても、確認が必要な行を含んだまま報告を確定しない、という分け方です。

elseとfinallyの役割

elseは、tryの中で例外が起きなかった場合に実行します。上の例では変換と検査に通った値だけを結果へ加える場所です。

finallyは例外の有無にかかわらず後片付けを行うために使います。ファイルならwithで管理できる場合もあります。finallyの中で新しい例外を出したり、returnしてしまったりすると、元の失敗が見えにくくなるので、必要な後片付けへ絞ります。

分からない失敗を隠さない

想定していない例外は、記録したうえでraiseし直す方法があります。エラーが起きたという事実を、呼び出した側へ伝えるためです。ログへ書いただけで成功の終了コードを返すと、定期実行側が正常と判断することがあります。

通知や投稿の処理では、応答が返らなくても相手側で完了している場合があります。そのような結果不明を、例外が出たから未実行と決めて再送しないことも必要です。例外処理の形だけでなく、どの操作を再実行してよいかまで、処理の内容に合わせて決めてください。

関連する作業

失敗の記録と、入力データを先に点検する方法は次の記事で確認できます。

参考資料

この記事を書いた人

Watanabeのアバター Watanabe サイト運営者

2020年よりブログ開始。
SEOが思いのほか性にあっていたようで現在に至る。
モットーは「勝率の高い選択をする」
AIは活用するが吉、最後は人間が息を吹き込む。
アートと科学を追求し、日々精進。
―――
収益:6~7桁をウゴウゴ。
サイト:ペラサイト~中規模サイトまで運営中。
案件:1000円以上の案件をメインに取組中。
打ち手:ブラックSEO~ホワイトSEOまで
―――

目次