プログラムを実行していると、予期せぬデータが入力されたり、ファイルが見つからなかったりといった理由でエラーが発生することがあります。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つの処理の中で複数種類のエラーが発生する可能性があります。例えば、数値以外の文字が入力された場合は TypeError や ValueError が発生します。
複数の 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を記述して、エラーの種類ごとに処理を分岐させることができます。
