9. 例外処理(try-except 文)¶
9.1 例外処理とは¶
プログラムを実行中に予期しないエラーが発生することがあります。これを例外と呼びます。例外処理は、プログラムがエラーで停止してしまうことを防ぎ、エラー発生時に特定の処理を行えるようにするための仕組みです。
Python では、try-except文を使って例外処理を行います。
9.2 try-except 文の基本構造¶
以下のような基本構造になっています。
tryブロック内に例外が発生する可能性のあるコードを記述します。exceptで特定の例外を捕捉し、処理を記述します。
9.3 具体例¶
9.3.1 ゼロ除算の例外処理¶
例えば、ゼロ除算の際にはZeroDivisionErrorという例外が発生します。
上記のコードでは、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}")
この例では、ValueErrorとZeroDivisionErrorをそれぞれ異なる方法で処理します。
9.5 すべての例外を捕捉する¶
全ての例外を捕捉したい場合は、except Exceptionを使用しますが、具体的な例外を上で捕捉してから使用するのがベストプラクティスです。
9.6 finally ブロック¶
finallyブロックは例外の有無に関わらず、必ず実行されるコードを記述します。
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"エラー: {e}")
finally:
print("この処理は必ず実行されます")
演習問題¶
演習 1: ゼロ除算の例外処理¶
ユーザーから2つの数値を入力として受け取り(仮に a = 10, b = 0 とします)、割り算を行うプログラムを作成してください。ゼロ除算が発生した場合は適切なエラーメッセージを表示してください。
解答例
演習 2: 型変換の例外処理¶
文字列を整数に変換するプログラムを作成してください。変換できない文字列の場合は適切なエラーメッセージを表示してください。
解答例
演習 3: リストのインデックスエラー¶
リスト numbers = [1, 2, 3, 4, 5] から要素を取得するプログラムを作成し、存在しないインデックスにアクセスした場合の例外処理を実装してください。
解答例
演習 4: 複数の例外処理¶
ユーザーから入力された文字列を整数に変換し、その数で10を割るプログラムを作成してください。型変換エラーとゼロ除算エラーの両方を処理してください。
解答例
演習 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