Pythonの例外処理:try-except文によるエラーハンドリングの基本と実践

プログラムを実行していると、予期せぬデータが入力されたり、ファイルが見つからなかったりといった理由でエラーが発生することがあります。Pythonでは、こうした実行時のエラーを**「例外(Exception)」**と呼びます。

例外が発生すると、通常プログラムはその時点で強制終了してしまいます。しかし、適切な「例外処理」を実装しておくことで、エラー発生時にもプログラムを落とさずに、エラーメッセージを表示して処理を継続させたり、安全に終了させたりすることが可能になります。

この記事では、try-except 文を使用した基本的な例外処理の実装方法について解説します。

目次

例外処理を行わない場合のリスク

まず、例外処理を行わずにエラーが発生するケースを見てみます。 例として、仕入れ総額と個数から、商品1つあたりの単価を計算する関数を考えます。

def calculate_unit_cost(total_cost, quantity):
    """
    総額(total_cost)を個数(quantity)で割って単価を表示する
    """
    cost = total_cost / quantity
    print(f"単価: {int(cost)}円")

# 1. 正常なケース
calculate_unit_cost(10000, 20)

# 2. エラーが発生するケース(個数が0)
# calculate_unit_cost(5000, 0)

実行結果:

単価: 500円
ZeroDivisionError: division by zero

個数に 0 を渡すと、割り算ができないため ZeroDivisionError が発生し、プログラムがクラッシュします。これでは、システム全体が停止してしまう可能性があります。

try-except 文による例外の捕捉

このような事態を防ぐために、try-except 文を使用します。

  • try ブロック: エラーが発生する可能性がある処理を記述します。
  • except ブロック: エラーが発生した場合に行う処理(リカバリー処理やログ出力)を記述します。

構文:

try:
    # 実行したい処理
except エラーの種類:
    # エラー発生時の処理

修正後のコード

先ほどの関数に例外処理を追加します。

def calculate_unit_cost_safe(total_cost, quantity):
    try:
        result = total_cost / quantity
        print(f"単価: {int(result)}円")
        
    except ZeroDivisionError:
        print("エラー: 個数に0を指定することはできません。処理をスキップします。")

# 実行テスト
print("--- ケース1: 正常 ---")
calculate_unit_cost_safe(10000, 20)

print("\n--- ケース2: ゼロ除算 ---")
calculate_unit_cost_safe(5000, 0)

print("\n--- 処理は継続しています ---")

実行結果:

--- ケース1: 正常 ---
単価: 500円

--- ケース2: ゼロ除算 ---
エラー: 個数に0を指定することはできません。処理をスキップします。

--- 処理は継続しています ---

エラーが発生してもプログラムは強制終了せず、except ブロック内のメッセージを表示した後、後続の処理(「処理は継続しています」の表示)が実行されていることがわかります。

例外の内容(メッセージ)を受け取る

どのようなエラーが起きたのか、詳細な情報を取得したい場合は、as キーワードを使って例外オブジェクトを変数に格納します。

    except ZeroDivisionError as e:
        print(f"エラーが発生しました: {e}")

複数の例外に対応する

プログラムでは、1つの処理の中で複数種類のエラーが発生する可能性があります。例えば、数値以外の文字が入力された場合は TypeErrorValueError が発生します。

複数の except ブロックを記述することで、エラーの種類ごとに異なる対応が可能です。

def robust_calculation(total, count):
    try:
        # 割り算を実行
        unit_price = total / count
        print(f"計算結果: {unit_price}")

    except ZeroDivisionError:
        # 0で割った場合
        print("エラー: 0除算は無効です。")

    except TypeError as e:
        # 数値以外(文字列など)が渡された場合
        print(f"エラー: 数値以外のデータが含まれています。詳細: {e}")

    except Exception as e:
        # 上記以外のすべての予期せぬエラー
        print(f"予期せぬエラーが発生しました: {e}")

# テスト
robust_calculation(3000, "5個")  # 文字列を渡してみる

実行結果:

エラー: 数値以外のデータが含まれています。詳細: unsupported operand type(s) for /: 'int' and 'str'

Exception はほぼ全ての例外の親クラスであるため、これを最後に記述しておくと、想定外のエラーも漏らさずキャッチできます(ただし、原因特定が難しくなるため、可能な限り具体的な例外クラスを指定することが推奨されます)。

まとめ

  • Pythonでは try-except 文を使って、実行時のエラー(例外)をハンドリングします。
  • 例外を捕捉することで、プログラムの強制終了を防ぎ、適切なエラーメッセージを表示したり、代替処理を行ったりできます。
  • except エラー型 as 変数: でエラーの詳細情報を取得できます。
  • 複数の except を記述して、エラーの種類ごとに処理を分岐させることができます。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次