Skip to content

9. 例外処理(try-except 文)

9.1 例外処理とは

プログラムを実行中に予期しないエラーが発生することがあります。これを例外と呼びます。例外処理は、プログラムがエラーで停止してしまうことを防ぎ、エラー発生時に特定の処理を行えるようにするための仕組みです。

Python では、try-except文を使って例外処理を行います。

9.2 try-except 文の基本構造

以下のような基本構造になっています。

try:
    # ここに例外が発生する可能性があるコード
    pass
except エラーの種類 as エラー変数:
    # 例外が発生したときの処理
    pass
  • tryブロック内に例外が発生する可能性のあるコードを記述します。
  • exceptで特定の例外を捕捉し、処理を記述します。

9.3 具体例

9.3.1 ゼロ除算の例外処理

例えば、ゼロ除算の際にはZeroDivisionErrorという例外が発生します。

try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"エラーが発生しました: {e}")

上記のコードでは、10 を 0 で割るとZeroDivisionErrorが発生します。しかし、except部分でこの例外を捕捉し、エラー内容を表示します。

9.3.2 ファイル読み込みの例外処理

存在しないファイルを読み込もうとするとFileNotFoundErrorが発生します。

try:
    with open('nonexistent_file.txt', 'r') as f:
        content = f.read()
except FileNotFoundError as e:
    print(f"ファイルが見つかりません: {e}")

この例では、存在しないファイルを開こうとするためFileNotFoundErrorが発生しますが、except内でそのエラーを処理しています。

9.4 複数の例外を処理する

複数の例外をそれぞれ異なる方法で処理することもできます。

try:
    num = int("a")  # 文字列を整数に変換
    result = 10 / num
except ValueError as e:
    print(f"整数への変換に失敗しました: {e}")
except ZeroDivisionError as e:
    print(f"ゼロで割ろうとしました: {e}")

この例では、ValueErrorZeroDivisionErrorをそれぞれ異なる方法で処理します。

9.5 すべての例外を捕捉する

全ての例外を捕捉したい場合は、except Exceptionを使用しますが、具体的な例外を上で捕捉してから使用するのがベストプラクティスです。

try:
    # コードブロック
    result = 10 / int("a")
except Exception as e:
    print(f"予期しないエラーが発生しました: {e}")

9.6 finally ブロック

finallyブロックは例外の有無に関わらず、必ず実行されるコードを記述します。

try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"エラー: {e}")
finally:
    print("この処理は必ず実行されます")

演習問題

演習 1: ゼロ除算の例外処理

ユーザーから2つの数値を入力として受け取り(仮に a = 10, b = 0 とします)、割り算を行うプログラムを作成してください。ゼロ除算が発生した場合は適切なエラーメッセージを表示してください。

解答例
a = 10
b = 0

try:
    result = a / b
    print(f"結果: {result}")
except ZeroDivisionError:
    print("エラー: ゼロで割ることはできません")

演習 2: 型変換の例外処理

文字列を整数に変換するプログラムを作成してください。変換できない文字列の場合は適切なエラーメッセージを表示してください。

解答例
text = "abc"

try:
    number = int(text)
    print(f"変換結果: {number}")
except ValueError:
    print(f"エラー: '{text}' は整数に変換できません")

# 正常に変換できる例
text2 = "123"
try:
    number2 = int(text2)
    print(f"変換結果: {number2}")
except ValueError:
    print(f"エラー: '{text2}' は整数に変換できません")

演習 3: リストのインデックスエラー

リスト numbers = [1, 2, 3, 4, 5] から要素を取得するプログラムを作成し、存在しないインデックスにアクセスした場合の例外処理を実装してください。

解答例
numbers = [1, 2, 3, 4, 5]
index = 10

try:
    value = numbers[index]
    print(f"インデックス {index} の値: {value}")
except IndexError:
    print(f"エラー: インデックス {index} は範囲外です(リストの長さ: {len(numbers)})")

演習 4: 複数の例外処理

ユーザーから入力された文字列を整数に変換し、その数で10を割るプログラムを作成してください。型変換エラーとゼロ除算エラーの両方を処理してください。

解答例
user_input = "0"  # または "abc" でテスト

try:
    number = int(user_input)
    result = 10 / number
    print(f"10 ÷ {number} = {result}")
except ValueError:
    print(f"エラー: '{user_input}' は有効な数値ではありません")
except ZeroDivisionError:
    print("エラー: ゼロで割ることはできません")

演習 5: finally ブロックの活用

ファイルを開いて読み込む処理をシミュレートし、例外が発生してもしなくても必ず「処理が完了しました」と表示するプログラムを作成してください。

解答例
filename = "nonexistent.txt"

try:
    print(f"{filename} を開きます...")
    # 実際にはファイルが存在しないのでエラーになる
    with open(filename, 'r') as f:
        content = f.read()
        print(content)
    print("ファイルの読み込みに成功しました")
except FileNotFoundError:
    print(f"エラー: {filename} が見つかりません")
except Exception as e:
    print(f"予期しないエラーが発生しました: {e}")
finally:
    print("処理が完了しました")

演習 6: 安全な数値入力関数

文字列を受け取り、整数に変換して返す関数 safe_int_input(text) を作成してください。変換できない場合は None を返すようにしてください。

解答例
def safe_int_input(text):
    try:
        return int(text)
    except ValueError:
        print(f"警告: '{text}' は整数に変換できません")
        return None

# テスト
result1 = safe_int_input("123")
print(f"結果1: {result1}")  # 出力: 123

result2 = safe_int_input("abc")
print(f"結果2: {result2}")  # 出力: None

# 実用例
value = safe_int_input("100")
if value is not None:
    print(f"値は {value} です")
else:
    print("無効な入力でした")

演習 7: カスタムエラーメッセージ

リストから要素を安全に取得する関数を作成してください。インデックスが範囲外の場合、わかりやすいエラーメッセージを表示してください。

解答例
def safe_get(lst, index):
    try:
        return lst[index]
    except IndexError:
        print(f"エラー: インデックス {index} は範囲外です")
        print(f"有効な範囲: 0 から {len(lst) - 1}")
        return None

# テスト
data = [10, 20, 30, 40, 50]

value1 = safe_get(data, 2)
print(f"取得した値: {value1}")  # 出力: 30

value2 = safe_get(data, 10)
print(f"取得した値: {value2}")  # 出力: None