try/except の概要(エラーを安全に処理してプログラムを続行)
try/except は、処理中に起きる例外(実行時エラー)を捕まえて、プログラムを安全に続行したり、分かりやすいメッセージを出したりするための構文です。try に「失敗しうる最小限の処理」を書き、except に「失敗時の対応」を書きます。適切に例外を扱うことで、ユーザー入力やファイル操作など不確実な場面でも、プログラムが止まらずに動き続けます。
try:
age = int(input("年齢(整数): ").strip())
print(f"来年は {age + 1} 歳")
except ValueError:
print("整数で入力してください")
Python基本構文と評価の流れ(ここが重要)
try と except の役割分担
try に「失敗しそうな処理」を入れ、そこで例外が起きると except にジャンプして対応します。try が成功したときは except は実行されません。失敗する可能性が低い処理まで広げず、「失敗しうる最小範囲」に try を絞るのが読みやすさのコツです。
try:
value = int(text.strip()) # ここだけが失敗しうる
except ValueError:
value = None # 失敗時の代替
Python例外の種類を「特定して」捕まえる
except は種類を指定できます。間違いを絞ることで、意図しないエラーまで飲み込まず、バグの発見を妨げません。複数種類はタプルでまとめて指定できます。
try:
result = 10 / x
except (ZeroDivisionError, TypeError):
result = None
Python例外オブジェクトを受け取る(as e)
メッセージや詳細が欲しいときは「as e」で受け取り、ログや画面に出せます。デバッグや運用時に便利です。
try:
open("data.txt", "r", encoding="utf-8")
except FileNotFoundError as e:
print(f"ファイルエラー: {e}")
Pythonelse と finally の活用(成功時と後始末を分離)
else は「例外が起きなかったときだけ」
try が成功した場合にだけ実行したい処理は else に置きます。try には「失敗しうる最小限」を、else には「成功前提の本処理」を置くと構造が明快です。
try:
value = int(input("数量: ").strip())
except ValueError:
print("整数で入力してください")
else:
print(f"在庫を {value} 個引き当てます")
Pythonfinally は「成功・失敗に関わらず必ず」
後始末(ファイルクローズ、ロック解放、接続切断など)は finally に置くと、例外の有無にかかわらず確実に実行されます。
f = None
try:
f = open("log.txt", "a", encoding="utf-8")
f.write("起動\n")
except OSError as e:
print(f"書き込み失敗: {e}")
finally:
if f:
f.close() # 必ず閉じる
Pythonよくあるパターン(入力・ファイル・再試行)
入力のバリデーション(失敗時に再試行)
ユーザー入力は失敗前提で設計します。例外をメッセージに変え、再試行ループで安全に正しい値へ導きます。
while True:
try:
age = int(input("年齢(整数): ").strip())
break
except ValueError:
print("整数で入力してください")
print(f"受付: {age}")
Pythonファイルの存在チェックと代替処理
見つからない場合は新規作成やデフォルト値に切り替えます。
from pathlib import Path
path = Path("data.txt")
try:
text = path.read_text(encoding="utf-8")
except FileNotFoundError:
print("ファイルがありません。初期データを作成します。")
path.write_text("seed\n", encoding="utf-8")
else:
print(text)
Python最大回数付きのリトライ
外部要因で失敗しうる処理は、上限付きで再試行します。成功で break、すべて失敗で通知します。
attempts = 0
success = False
while attempts < 3 and not success:
attempts += 1
try:
success = do_task() # 例: ネットワーク処理
except TimeoutError:
print("タイムアウト。再試行します...")
if not success:
print("3回失敗しました")
Python設計の指針(重要ポイントを深掘り)
「何をいつ捕まえるか」を明確にする
- 失敗しうる最小範囲だけ try に入れると、例外の原因が特定しやすくなります。
- except は種類を特定する。bare except(種類指定なし)は、Ctrl+C や重要なシステム例外まで飲み込むため避けます。
エラーメッセージはユーザー視点で
内部的な例外名ではなく、ユーザーに意味が通る説明を返します。ログには詳細(例外オブジェクト、スタック)を残すと、のちの調査が容易です。
例外を「握りつぶさない」
本当に無視してよい場合以外は、ログを残す、代替処理を明示する、必要なら再送出(raise)するなど、意図を示します。
try:
risky()
except CustomError as e:
log_error(e)
raise # 上位に知らせる(再送出)
Python例外階層を理解して適切に選ぶ
ValueError(値の不正)、TypeError(型不一致)、KeyError(辞書キー不存在)、IndexError(範囲外)、ZeroDivisionError(ゼロ除算)など「よく起きる種類」を覚えておくと、except の設計がスムーズになります。
例題で身につける(定番から一歩先まで)
例題1:CSVの数値列のクレンジング
rows = ["120", "abc", "340", " 560 "]
nums = []
for s in rows:
try:
nums.append(int(s.strip()))
except ValueError:
# 数値でない行はスキップ(ログだけ残す)
print(f"スキップ: {s!r}")
print(nums) # [120, 340, 560]
Python例題2:辞書アクセスの安全化
def show_user(user: dict):
try:
name = user["name"]
age = user["age"]
except KeyError as e:
print(f"不足フィールド: {e}")
else:
print(f"{name}({age}歳)")
Python例題3:数値計算のガードとメッセージ
def safe_div(a: float, b: float) -> float | None:
try:
return a / b
except ZeroDivisionError:
print("分母が0のため計算できません")
return None
Python例題4:「失敗しうる最小範囲」に絞る try
def total_price(text_price: str, qty: int) -> int | None:
try:
price = int(text_price.strip()) # ここだけが失敗しうる
except ValueError:
return None
return price * qty
Pythonまとめ
try/except は「失敗を想定した安全運転」を可能にする要です。失敗しうる最小範囲に try を絞り、except は種類を特定、ユーザーには分かりやすく、ログには詳細を。成功時は else、後始末は finally に分離して構造を明確化します。再試行や代替処理の設計を組み込み、無視してよい例外だけを pass する。こうした基本を徹底すれば、初心者でも堅牢で見通しの良い例外処理を書けるようになります。
