導入
第5章では try / except でエラーを捕まえる基本を学びました。ここではその発展として、「エラーが起きなかったときだけ実行する」「エラーの有無にかかわらず必ず実行する」「自分からエラーを発生させる」「自分専用のエラーの種類を作る」という、実務でよく使う4つの道具を学びます。
説明
try には except に加えて else(エラーが起きなかったときだけ実行)と finally(エラーの有無にかかわらず必ず実行)を付けられます。
flowchart TB t["try: 危険な処理"] -->|"エラーなし"| e["else: 成功時だけ実行"] t -->|"エラーあり"| x["except: エラー時の対応"] e --> f["finally: 必ず実行"] x --> f
def divide(a, b):
try:
result = a / b
except ZeroDivisionError:
print("エラー: 0では割れません")
else:
print(f"結果: {result}")
finally:
print("計算を終了します")
divide(10, 2)
divide(10, 0)
finally は「後片付け」を書く場所としてよく使われます(ファイルを閉じる、接続を切るなど)。else は「try の中身は成功したが、その後の処理はエラー対応に巻き込みたくない」ときに使います。
エラーは受け止めるだけでなく、自分から発生させることもできます。raise を使います。
def check_age(age):
if age < 0:
raise ValueError("年齢は0以上にしてください")
return age
try:
check_age(-5)
except ValueError as e:
print(f"入力エラー: {e}")
さらに、組み込みのエラー(ValueError や ZeroDivisionError など)だけでなく、自分専用のエラーの種類を作ることもできます。Exception を継承したクラスを作るだけです。
class InsufficientFundsError(Exception):
"""残高不足を表す独自の例外"""
pass
def withdraw(balance, amount):
if amount > balance:
raise InsufficientFundsError(f"残高不足: {amount - balance}円足りません")
return balance - amount
try:
print(withdraw(1000, 3000))
except InsufficientFundsError as e:
print(e)
独自の例外クラスを作ると、「このエラーは自分のプログラム特有の問題だ」とはっきり区別できます。呼び出す側も except InsufficientFundsError: のようにピンポイントで対応できて、コードの意図が伝わりやすくなります。
やってみよう
divide に渡す数を変えたり、withdraw の残高・引き出し額を変えたりして、else / finally / raise がどのタイミングで動くか確かめましょう。
演習
独自の例外クラス InsufficientFundsError を定義し(Exception を継承するだけでよい)、withdraw(balance, amount) 関数を作ってください。amount が balance より大きいときは raise InsufficientFundsError(f"残高不足: {amount - balance}円足りません") で例外を送出し、そうでなければ balance - amount を返します。withdraw(1000, 1500) を try / except で呼び出し、捕まえたエラーメッセージを表示してください(結果は 残高不足: 500円足りません)。
ヒント1を見る
class InsufficientFundsError(Exception): pass で独自例外を定義します。
ヒント2を見る
try: print(withdraw(1000, 1500)) except InsufficientFundsError as e: print(e) の形で呼び出します。