Pythonのexceptによる例外処理の基本とエラーハンドリングの使い方をわかりやすく解説

スポンサーリンク
スポンサーリンク
amazon
スマイルSALE
--:--:--
ad. 価格範囲を指定して商品を探せます

exceptの概要

例外処理のエラーハンドリング Python予約語

except

概要 except(エクセプト)は、try ブロックの内部で発生した例外(プログラムの実行中に起きるエラー)をキャッチし、プログラムを強制終了させることなく適切な代替処理をさせるためのキーワードです。エラーハンドリング(例外処理)に必須の要素です。

わかりやすく説明 except は、プログラムの世界における「セーフティネット(受け皿)」です。「もしエラーが起きてしまったら、画面を真っ赤にしてクラッシュする代わりに、この処理を行ってね」とあらかじめPythonに指示を出しておく役割を持っています。

  • try ブロックと必ずセットで記述し、エラーが発生したときの逃げ道を作ります。
  • 「ゼロで割ったとき」「文字を数字に変換しようとしたとき」など、エラーの種類(例外型)を指定して別々の対策を取ることができます。
  • 発生したエラーの「生の内容(エラーメッセージ)」を変数として受け取り、ログに残すことも可能です。

exceptの考え方をイメージで理解

exceptの基本的な使い方

数学的に禁止されている「ゼロ除算(0での割り算)」が発生した際に、プログラムを止めずにエラーメッセージをスマートに表示する例です。

# 例外処理の基本
try:
    result = 10 / 0  # ここでゼロ除算エラー(ZeroDivisionError)が発生!
except ZeroDivisionError:
    # エラーを検知すると、すぐさまこちらの処理にワープします
    print("システムエラー:ゼロで数字を割ることはできません。")
  • try の中でエラーが起きた瞬間、それより下の行の処理は中断され、合致する except ブロックへと処理が移ります。

exceptで複数の例外を個別にキャッチ

ユーザーの入力内容によって、「文字が入ってきた場合」と「0が入力された場合」で別々の親切なエラーメッセージを出し分ける例です。

# 複数の例外を出し分けて処理
try:
    user_input = input("数字を入力してください: ")
    num = int(user_input)  # 文字列が入力されると ValueError が発生
    result = 10 / num      # 0が入力されると ZeroDivisionError が発生
except ZeroDivisionError:
    print("0以外の数値を入力してください。")
except ValueError:
    print("エラー:アルファベットや漢字ではなく、半角数字を入力してください。")

exceptで複数の例外をまとめてキャッチ

エラーの種類に関わらず、「入力が不正である」という同じ対応(一括処理)を行いたい場合は、エラー名をカッコ () で囲ってタプルにします。

# まとめて例外をキャッチ
try:
    num = int(input("数字を入力してください: "))
    result = 10 / num
except (ZeroDivisionError, ValueError):
    # どちらのエラーが発生しても、このブロックが動きます
    print("入力された値が正しくないため、計算をスキップしました。")

except asを使ってエラーの詳細(メッセージ)を取得

as の後ろに変数名(慣習的に e など)を添えることで、Pythonが内部で出力した本来のエラーメッセージの内容を直接取得して利用できます。

# 例外の詳細を表示
try:
    result = 10 / 0
except ZeroDivisionError as e:
    # 変数 e の中に「division by zero」という詳細メッセージが入っています
    print(f"エラー内容を開発ログに記録しました: {e}")

exceptの実践的な使用例

指定したファイルがパソコン内に存在しなかった場合に、エラー画面を出さずに代替処理に切り替える実務的なコードです。

# ファイル読み込みの安全化
try:
    with open("setting_file.txt", "r") as file:
        config = file.read()
except FileNotFoundError:
    print("設定ファイルが見つかりません。デフォルト値で起動します。")
    config = "default_mode=True"

exceptの注意点

  • エラー名を何も書かない「裸のexcept」は原則禁止except: とだけ書くと、すべてのエラーを無差別に吸い込んでしまいます。これを行うと、記述ミス(タイポ)や予期せぬ重大なバグまでもがすべて隠蔽されてしまい、原因究明が不可能になるため避けてください。
    # 【悪い例】すべてのエラーを隠してしまう
    try:
        pirnt("こんにちは") # printのスペルミス(NameError)
    except:
        pass # 本来気づくべき重大なミスが無視されてプログラムが動き続けてしまう
    
    # 【正しい例】想定されるエラーだけを指名手配する
    try:
        # 処理
    except FileNotFoundError:
        # ファイルがない時の対策
  • Exceptionを指定した広域キャッチの使いどころ:どうしても予期せぬエラー全般を網羅したい場合は、except Exception as e: と記述しましょう。これであれば最低限、エラーの内容(e)をログに残すことができるため安全性が担保されます。
    # 予期せぬエラーを安全にロギングする
    try:
        # 何が起きるか分からない外部通信など
        response = net_connect()
    except Exception as e:
        print(f"未知のエラーを検知しました。管理者に報告します: {e}")
  • exceptブロック内での新たなエラーに注意except の中に書いたコード自体でエラーが発生してしまった場合、それはキャッチされずプログラムはクラッシュします。避難訓練のルート(except の中身)は常にシンプルで安全なコードを心がけましょう。

exceptのよくある質問

Q: `except` の中で `pass`(何もしない)を使っても問題ないですか?
A: 文法的には問題ありませんが、実務では「意図が明確な場合」を除いて非推奨です。エラーを完全に無視すると、裏で何が起きているか分からなくなるため、最低限 print で画面に出すか、ログファイルに書き出す処理を挟むのがスマートです。

# あまり良くない例(何が起きたか一切不明になる)
except ValueError:
    pass

# 推奨される例(せめてログを出す)
except ValueError:
    print("Warning: 無効な値がスキップされました。")
Q: エラーが発生したかどうかに関わらず、最後に必ず実行したい処理がある場合はどう書きますか?
A: try-except 構文の末尾に finally というキーワードを追加します。これにより、エラーなく成功した場合でも、エラーが起きて except が動いた場合でも、最終的に必ず指定コード(ファイルのクローズ処理など)を実行させることができます。

try:
    print("データ処理中...")
except Exception:
    print("エラー発生")
finally:
    print("すべての後片付けが完了しました。") # 必ず最後に実行される

まとめ

except は、プログラムが不測の事態に直面した際、パニックを起こして強制終了するのを防ぐための極めて重要な防衛用キーワードです。

  • try ブロック内でエラー(例外)が起きた際の、専用のエスケープルートを指定する。
  • ZeroDivisionErrorValueError など、具体的なエラー名を指定して的確な対応策を仕込める。
  • 何も指定しない無差別なキャッチはバグを見失う原因になるため、適切な範囲のエラー指定を行う。

日常のシステム開発において、エラーが絶対に起きないプログラムを作ることは不可能です。except を上手に使いこなし、エラーが起きても優しくリカバーできる強固なプログラムを目指しましょう。