Python クラスメンバーの遅延初期化 質問する

Python クラスメンバーの遅延初期化 質問する

アクセスされた場合のみクラス メンバーを初期化する Python の方法を知りたいです。以下のコードを試してみましたが、うまくいきましたが、これよりも簡単な方法はありますか?

class MyClass(object):

    _MY_DATA = None

    @staticmethod
    def _retrieve_my_data():
        my_data = ...  # costly database call
        return my_data

    @classmethod
    def get_my_data(cls):
        if cls._MY_DATA is None:
            cls._MY_DATA = MyClass._retrieve_my_data()
        return cls._MY_DATA

ベストアンサー1

あなたは@propertyの上メタクラスその代わり:

class MyMetaClass(type):
    @property
    def my_data(cls):
        if getattr(cls, '_MY_DATA', None) is None:
            my_data = ...  # costly database call
            cls._MY_DATA = my_data
        return cls._MY_DATA


class MyClass(metaclass=MyMetaClass):
    # ...

これにより、my_dataクラスに属性が作成され、高価なデータベース呼び出しは、アクセスしようとするまで延期されますMyClass.my_data。データベース呼び出しの結果は、に格納されてキャッシュされMyClass._MY_DATA、呼び出しは一度クラスのために。

Python 2の場合はclass MyClass(object):__metaclass__ = MyMetaClass属性クラス定義本体にメタクラスを添付します。

デモ:

>>> class MyMetaClass(type):
...     @property
...     def my_data(cls):
...         if getattr(cls, '_MY_DATA', None) is None:
...             print("costly database call executing")
...             my_data = 'bar'
...             cls._MY_DATA = my_data
...         return cls._MY_DATA
... 
>>> class MyClass(metaclass=MyMetaClass):
...     pass
... 
>>> MyClass.my_data
costly database call executing
'bar'
>>> MyClass.my_data
'bar'

これが機能するのは、 のようなデータ記述子propertyがオブジェクトの親タイプで検索されるためです。 であるクラスの場合type、 はtypeメタクラスを使用して拡張できます。

おすすめ記事