7.1 カスタム例外の作成
時々、Pythonの標準例外はアプリケーションのニーズを完全に満たさないことがあります。そのような場合には、ベースクラス Exceptionまたは他の適切な例外クラスを継承して独自の例外を作成することができます。
カスタム例外の作成基本
カスタム例外の作成には、ベースクラスExceptionを継承した新しいクラスを定義することが含まれます。エラーについての追加情報を提供するために、クラスに独自のメソッドや属性を加えることができます。
簡単なカスタム例外の作成例
ステップ1: カスタム例外の定義
class MyCustomError(Exception):
"""カスタム例外のためのクラス。"""
pass
ステップ2: カスタム例外の使用
def check_value(value):
if value < 0:
raise MyCustomError("値はゼロ未満であってはならない")
try:
check_value(-1)
except MyCustomError as e:
print(f"カスタム例外が発生しました: {e}")
とても簡単ですね。例外は必ずExceptionクラスまたはその子孫クラスを継承している必要があります。
7.2 追加の属性を持つ例外の作成
エラーの発生についての追加情報を渡すために、例外クラスに属性やメソッドを追加することができます。
例:
class NegativeValueError( Exception ):
"""負の値のカスタム例外のためのクラス。"""
def __init__(self, value, message = "値はゼロ未満であってはならない"):
self.value = value
self.message = message
super().__init__(self.message)
def __str__(self):
return f'{self.message}: {self.value}'
追加の属性を持つ例外の使用
def check_value(value):
if value < 0:
raise NegativeValueError(value)
try:
check_value(-1)
except NegativeValueError as e:
print(f"カスタム例外が発生しました: {e}")
私たちの例外はExceptionクラスを継承したクラスです。したがって、他のクラスと同様にすべてのことができます: フィールド、メソッド、コンストラクタのパラメータを追加するなど。
あなたや他のプログラマーがあなたの例外をキャッチすることを簡単にするために。
7.3 カスタム例外の階層の作成
より複雑なアプリケーションのために、カスタム例外の階層を作成することが役立ちます。これにより、関連する例外をグループ化し、それらの処理を容易にします。
例:
class ApplicationError(Exception):
"""すべてのアプリケーション例外のための基本クラス。"""
pass
class NegativeValueError(ApplicationError):
"""負の値のカスタム例外のためのクラス。"""
def __init__(self, value, message="値はゼロ未満であってはならない"):
self.value = value
self.message = message
super().__init__(self.message)
def __str__(self):
return f'{self.message}: {self.value}'
class ValueTooLargeError(ApplicationError):
"""あまりにも大きい値のカスタム例外のためのクラス。"""
def __init__(self, value, message="値が大きすぎます"):
self.value = value
self.message = message
super().__init__(self.message)
def __str__(self):
return f'{self.message}: {self.value}'
カスタム例外の階層の使用
def check_value(value):
if value < 0:
raise NegativeValueError(value)
elif value > 100:
raise ValueTooLargeError(value)
try:
check_value(150)
except NegativeValueError as e:
print(f"例外が発生しました: {e}")
except ValueTooLargeError as e:
print(f"例外が発生しました: {e}")
except ApplicationError as e:
print(f"アプリケーションの共通例外: {e}")
7.4 例外キャッチの順序
同じ階層の例外をキャッチする場合は、正しい順序で指定することが重要です。ブロック内のコード exceptが同時に実行されることは決してありませんが、基底例外クラスは、すべての子孫クラスの例外をキャッチすることができるからです。
例えば、コード:
def check_value(value):
if value < 0:
raise NegativeValueError(value)
elif value > 100:
raise ValueTooLargeError(value)
try:
check_value(150)
except ApplicationError as e: # ApplicationError およびそのすべての子孫の例外をキャッチする
print(f"アプリケーションの共通例外: {e}")
except ブロックは ApplicationError 型の例外およびそのすべてのクラス子孫の例外をキャッチします。
すべての例外が Exception クラスの子孫であるため、そのようなコードはすべての例外をキャッチします:
def check_value(value):
if value < 0:
raise NegativeValueError(value)
elif value > 100:
raise ValueTooLargeError(value)
try:
check_value(150)
except Exception as e:
print(f"すべての例外をキャッチ: {e}")
except ApplicationError as e: # このコードは決して実行されません
print(f"アプリケーションの共通例外: {e}")
例外をexcept ApplicationError ブロックでキャッチすることは決してありません。なぜなら except Exception ブロックは Exception 型の例外とそのすべての子孫の例外をキャッチしてしまうからです。
ソリューション
したがって、例外は継承の逆順にキャッチするのが一般的です: Exception クラスに近いほど、下に位置します。
例:
def check_value(value):
if value < 0:
raise NegativeValueError(value)
elif value > 100:
raise ValueTooLargeError(value)
try:
check_value(150)
except NegativeValueError as e:
print(f"例外が発生しました: {e}")
except ApplicationError as e:
print(f"アプリケーションの共通例外: {e}")
except Exception as e:
print(f"すべての例外をキャッチ: {e}")
この例では、except ブロックは継承の階層に沿って配置されています。最初に NegativeValueError のようなより特定の例外がキャッチされ、次に ApplicationError のようなより一般的な例外がキャッチされます。 これにより、例外が正しく処理され、より一般的なハンドラーが例外をキャッチする前に、より専門化された except のブロックがそれを処理することを可能にします。
GO TO FULL VERSION