Pythonでカスタム例外とデコレータを組み合わせる方法

この記事では、Pythonにおいてカスタム例外とデコレータを組み合わせる技術について詳しく解説します。具体的なコード例を通じて、このテクニックがどのように有用であるのか、その仕組みと応用例を2つ紹介します。

目次

はじめに:カスタム例外とデコレータの必要性

カスタム例外とデコレータは、Pythonでより高度なプログラミングを行う上で非常に有用な機能です。カスタム例外を使用することで、より詳細なエラーハンドリングが可能になります。一方で、デコレータを利用すると、コードの再利用性と可読性が高まります。

カスタム例外とは

標準的な例外クラスでは表現できない独自のエラーケースを扱うために、開発者が定義する例外クラスです。

デコレータとは

関数やメソッドに対して、その前後に何らかの処理を追加するための構文です。これによって、コードの再利用が容易になります。

カスタム例外の基本的な作成方法

まずは、カスタム例外の基本的な作り方について解説します。


class MyException(Exception):
    def __init__(self, message):
        self.message = message
        super().__init__(self.message)

このコードでは、`Exception` クラスを継承して、独自の例外`MyException`を作成しています。`message`という属性を持ち、エラーメッセージを外部から受け取れるようにしています。

デコレータの基本的な作成方法

次に、基本的なデコレータの作成方法です。


def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        func(*args, **kwargs)
        print("Something is happening after the function is called.")
    return wrapper

このデコレータ`my_decorator`は、関数が呼び出される前後にメッセージを出力します。

カスタム例外とデコレータの組み合わせ

さて、これらの概念を組み合わせるとどうなるのでしょうか。


class ValidateInputException(Exception):
    def __init__(self, message):
        self.message = message
        super().__init__(self.message)

def validate_input(func):
    def wrapper(*args, **kwargs):
        if not args:
            raise ValidateInputException("No arguments provided.")
        func(*args, **kwargs)
    return wrapper

@validate_input
def my_function(x):
    print(f"Argument received: {x}")

try:
    my_function()
except ValidateInputException as e:
    print(e)

この例では、デコレータ`validate_input`が関数`my_function`の引数をチェックしています。引数が提供されていない場合、カスタム例外`ValidateInputException`がスローされます。

応用例1: 複数のカスタム例外とデコレータ

より複雑なバリデーションが必要な場合は、複数のカスタム例外を使って処理できます。


class NegativeValueException(Exception):
    pass
class ZeroValueException(Exception):
    pass
def validate_positive(func):
    def wrapper(x):
        if x < 0:
            raise NegativeValueException("Negative value is not allowed.")
        elif x == 0:
            raise ZeroValueException("Zero is not allowed.")
        func(x)
    return wrapper
@validate_positive
def square_root(x):
    print(f"Square root of {x} is {x ** 0.5}")
try:
    square_root(-1)
except NegativeValueException as e:
    print(e)
try:
    square_root(0)
except ZeroValueException as e:
    print(e)

応用例2: 複数のデコレータの組み合わせ

複数のデコレータを組み合わせることも可能です。


def another_decorator(func):
    def wrapper(*args, **kwargs):
        print("Another decorator is called.")
        func(*args, **kwargs)
    return wrapper

@another_decorator
@validate_positive
def square_root(x):
    print(f"Square root of {x} is {x ** 0.5}")

この例では、`another_decorator`と`validate_positive`が組み合わされています。

まとめ

カスタム例外とデコレータを組み合わせることで、エラーハンドリングとコードの再利用性が高まります。このテクニックを使うことで、よりロバストでメンテナンスしやすいコードを書くことができるでしょう。

コメント

コメントする

目次