Pythonでクラスのアノテーションとデコレータを組み合わせる方法

この記事では、Pythonでクラスのアノテーションとデコレータを組み合わせて使う方法について詳しく解説します。具体的なコード例とその解説、応用例を含めています。

目次

クラスのアノテーションとデコレータとは

クラスのアノテーションは、クラスやメソッド、プロパティにメタデータを付与する方法です。デコレータは、関数やクラスの振る舞いを変更したり拡張したりするための強力なツールです。この二つを組み合わせることで、より高度なプログラミングが可能となります。

アノテーションの基本

Pythonでは、関数や変数に対して型情報などのメタデータをアノテーションとして付与できます。これによってコードが読みやすくなり、エディタやIDEが型チェックを行いやすくなります。

アノテーションの例

def add(a: int, b: int) -> int:
    return a + b

デコレータの基本

デコレータは、関数やクラスに特定の処理を追加するための構文です。具体的には、デコレータ関数が既存の関数やクラスを受け取り、新たな関数やクラスを返す形で動作します。

デコレータの例

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

@my_decorator
def say_hello():
    print("Hello!")

クラスのアノテーションとデコレータの組み合わせ

クラスのアノテーションとデコレータを組み合わせることで、コードの可読性と再利用性を高めることができます。

基本例

def class_decorator(cls):
    cls.new_attribute = "I'm a new attribute!"
    return cls

@class_decorator
class MyClass:
    pass

この例では、`class_decorator`が`MyClass`に`new_attribute`という新しい属性を追加しています。

応用例1:ロギング

import logging

def logging_decorator(cls):
    logging.basicConfig(level=logging.INFO)

    def wrapper(*args, **kwargs):
        logging.info(f"{cls.__name__} class instance created")
        return cls(*args, **kwargs)
    
    return wrapper

@logging_decorator
class Person:
    def __init__(self, name: str):
        self.name = name

この応用例では、`Person`クラスがインスタンス化されるたびにロギングが行われます。

応用例2:シングルトンパターン

def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class SingletonClass:
    def __init__(self, value):
        self.value = value

この応用例では、シングルトンパターンを実装しています。これにより、`SingletonClass`は一度しかインスタンス化されません。

応用例3:キャッシング

def caching_decorator(cls):
    cache = {}
    def wrapper(*args):
        if args in cache:
            return cache[args]
        else:
            obj = cls(*args)
            cache[args] = obj
            return obj
    return wrapper

@caching_decorator
class ExpensiveClass:
    def __init__(self, value):
        print(f"Creating instance with value: {value}")
        self.value = value

この応用例では、キャッシングを行っています。同じパラメータで`ExpensiveClass`が複数回インスタンス化される場合、新しいインスタンスを作成せずにキャッシュから取得します。

まとめ

Pythonのクラスのアノテーションとデコレータを

組み合わせることで、高度な機能を簡単に実装できるようになります。ロギング、シングルトン、キャッシングなどの応用例を通じて、その力強さを実感できたかと思います。

コメント

コメントする

目次