Pythonカスタム例外マスター:実践ガイド
Pythonカスタム例外
このチュートリアルでは、ニーズに合わせたカスタム例外の定義方法を実践例で学びます。
Pythonはプログラムが予期せぬ状況に遭遇した際にエラーを通知する多くの組み込み例外を提供します。しかし、組み込み例外では遭遇した問題を正確に記述できない場合があります。そんなとき、独自のカスタム例外タイプを作成することでコードをより明確で保守しやすくできます。
カスタム例外の作成
Pythonでカスタム例外を定義するのは簡単:組み込みExceptionクラス(またはそのサブクラス)を継承した新しいクラスを作成するだけです。標準例外の多くはExceptionから派生しているため、カスタムクラスはPythonのエラー処理システムとシームレスに統合されます。
> >>> class CustomError(Exception):
... pass
...
> >>> raise CustomError
Traceback (most recent call last):
...
__main__.CustomError
> >>> raise CustomError("An error occurred")
Traceback (most recent call last):
...
__main__.CustomError: An error occurred
ここではCustomErrorがExceptionを継承したユーザー定義例外です。raiseで発生させ、オプションでメッセージを付与できます。大規模プロジェクトでは、すべてのカスタム例外を専用モジュール(例:exceptions.pyやerrors.py)に配置するのが一般的で、これにより容易に特定・保守できます。
例:Pythonでのユーザー定義例外
以下のプログラムは、カスタム例外をユーザー入力のガイドに使用する方法を示します。ユーザーが格納値を当てるまで数値入力を繰り返し求めます。推測値が大きいか小さいかのヒントを、専用例外を発生させて提供します。
# Pythonユーザー定義例外の定義
class Error(Exception):
"""他の例外の基底クラス"""
pass
class ValueTooSmallError(Error):
"""入力値が小さすぎるときに発生"""
pass
class ValueTooLargeError(Error):
"""入力値が大きすぎるときに発生"""
pass
# 目標数値
number = 10
# 正解まで繰り返し
while True:
try:
i_num = int(input("Enter a number: "))
if i_num < number:
raise ValueTooSmallError
elif i_num > number:
raise ValueTooLargeError
break
except ValueTooSmallError:
print("This value is too small, try again!")
print()
except ValueTooLargeError:
print("This value is too large, try again!")
print()
print("Congratulations! You guessed it correctly.")
サンプル実行:
Enter a number: 12 This value is too large, try again! Enter a number: 0 This value is too small, try again! Enter a number: 8 This value is too small, try again! Enter a number: 10 Congratulations! You guessed it correctly.
この例では基底クラスErrorが2つの具体的エラータイプの共通祖先を提供します。このアプローチで例外階層を明確に保ち、望めば単一のexcept Error節で関連エラーを一括捕捉できます。
例外クラスのカスタマイズ
カスタム例外は追加データを保持したり、より情報豊かなメッセージを提示したりできます。これには__init__のオーバーライド、任意で__str__のオーバーライドが必要です。以下は給与検証シナリオを例示します。
class SalaryNotInRangeError(Exception):
"""入力給与のエラーのための例外。
Attributes:
salary -- エラーを引き起こした入力給与
message -- エラーの説明
"""
def __init__(self, salary, message="Salary is not in (5000, 15000) range"):
self.salary = salary
self.message = message
super().__init__(self.message)
salary = int(input("Enter salary amount: "))
if not 5000 < salary < 15000:
raise SalaryNotInRangeError(salary)
出力
Enter salary amount: 2000 Traceback (most recent call last): File "<string>", line 17, in <module> raise SalaryNotInRangeError(salary) __main__.SalaryNotInRangeError: Salary is not in (5000, 15000) range
__init__をオーバーライドすることで、例外が問題の値を保持できます。カスタム文字列表現が必要なら、以下のように__str__をオーバーライドします:
class SalaryNotInRangeError(Exception):
"""入力給与のエラーのための例外。
Attributes:
salary -- エラーを引き起こした入力給与
message -- エラーの説明
"""
def __init__(self, salary, message="Salary is not in (5000, 15000) range"):
self.salary = salary
self.message = message
super().__init__(self.message)
def __str__(self):
return f'{self.salary} → {self.message}'
salary = int(input("Enter salary amount: "))
if not 5000 < salary < 15000:
raise SalaryNotInRangeError(salary)
出力
Enter salary amount: 2000 Traceback (most recent call last): File "/home/user/untitled.py", line 20, in <module> raise SalaryNotInRangeError(salary) __main__.SalaryNotInRangeError: 2000 → Salary is not in (5000, 15000) range
例外処理パターンの詳細についてはPython例外処理チュートリアルを参照。
堅牢なアプリケーション設計についてはPythonオブジェクト指向プログラミングを参照。
Python
- Python データ型マスター: 実践ガイド
- Python 演算子完全マスター: 包括的ガイド
- Python pass文完全マスター: 実践ガイド
- Python 関数引数完全マスター: 位置引数・キーワード引数・デフォルト引数
- Python辞書完全ガイド:作成、操作、高度なテクニック
- Pythonエラーと組み込み例外をマスターする
- Pythonオブジェクト指向プログラミング完全ガイド:クラス、継承、カプセル化、ポリモーフィズム
- Python継承マスター:概念、構文、実践例
- Pythonイテレータ完全ガイド:仕組みと自作方法
- Python type()とisinstance()の理解:実例付き解説
- Python例外処理をマスター:包括的ガイド