シングルモード(Python実装)

2978 ワード

ジルコニウム単例モードは、一般的なソフトウェア設計モードである.そのコア構造には、単一の例と呼ばれる特殊なクラスが1つしか含まれていません.システムにおいて、このモードを適用するクラスは1つのクラスに1つのインスタンスしかないことを、単一のモードで保証することができる.すなわち、クラスにはオブジェクトインスタンスが1つしかありません.
適用性単一モードの適用には、一般的に次の条件があります.
  • リソース共有の場合、リソース操作によるパフォーマンスやロスなどを回避します.ログ・ファイルなどの構成を適用します.
  • 制御リソースの場合、リソース間の相互通信を容易にする.スレッドプールなどです.

  • アプリケーションシーン:
  • のウェブサイトのカウンタも、一般的には単例モードで実現され、そうでなければ同期しにくい.
  • アプリケーションのログアプリケーションは、一般的に単一のモードで実装されます.これは、共有されたログファイルが常に開いているためです.1つのインスタンスしか操作できないため、コンテンツが追加されにくいためです.
  • Webアプリケーションのコンフィギュレーションオブジェクトの読み取りは、コンフィギュレーションファイルが共有されるリソースであるため、一般的には単一のモードも適用される.  

  • スタート
      単例モードを実現する前に,使用した知識点を紹介する.
    1. __new__
      __init__メソッドは、通常、クラスインスタンスを初期化するときに使用されます.でも_init__クラスをインスタンス化するときに最初に呼び出されるメソッドではなく、最初に呼び出されるメソッドは実際には_new__メソッド、_init__クラスインスタンスが作成された後に呼び出され、_new__メソッドは、このクラスインスタンスを作成する方法です.
  • objectから継承された新しいクラスがあります.new__
  • __new__インスタンス化するクラスを表す少なくとも1つのパラメータclsが必要であり、このパラメータはインスタンス化時にPython解釈器によって自動的に
  • を提供する.
  • __new__インスタンス化されたインスタンスを返す戻り値が必要です.これは自分で実現します.new__親_をreturnできることに注意してください.new__出てきた例、または直接objectの_new__出てきた例
  • __init__パラメータselfがあります.これです.new__返されるインスタンス、_init__で_new__の基礎の上でいくつかのその他の初期化の動作を完成することができて、_init__戻り値
  • は不要
  • 若_new__現在のクラスclsのインスタンスが正しく返されていません.init__呼び出されません.親のインスタンスでも
  • はできません.
    2. __dict__
      python中_dict__オブジェクトのプロパティの一部が格納されます.クラスとインスタンスはそれぞれ独自の__を持っています.dict__,インスタンスはクラスの__を共有します.dict__.
    3.装飾器
    私のもう一つのブログPythonの閉鎖と装飾器を参考にしてください.
    インプリメンテーション
    1.書き換え_new__方法
    書き換えにより_new__メソッドクラスから継承されたクラスには1つのインスタンスしか作成できません
    class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            temp = super(Singleton, cls)
            cls._instance = temp.__new__(cls, *args, **kwargs)
        return cls._instance
    
    class MyClass(Singleton):
        p = '   '
    

    2.アクセサリーを使う
      装飾器を実現した後、クラスを装飾すれば1つの単例クラスを実現することができる.
    def singleton(cls, *args, **kwargs)
        instances = {}
        def get_instance():
            if cls not in instances:
                instances[cls] = cls(*args, **kwargs)
                return instance[cls]
            return get_instance
    
    @singleton
    class MyClass:
        p = '   '
    

    3.使用_dict__共有プロパティ
    すべてのインスタンスの_dict__インスタンスのdictをクラス変数に設定するには、同じに設定します.
    class Singleton(object):
        _state = {}
        def __new__(cls, *args, **kwargs):
            _instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
            _instance.__dict__ = cls._state
            return _instance
    
    class MyClass(Singleton):
        p = '   '
    

      この方法で単一のインスタンスモードを実装し、毎回新しいインスタンスが作成されますが、これらのインスタンスは同じデータで動作します.
    締めくくり
    次のコードは、各方法で実装されたシングル・インスタンス・モードで作成されたインスタンスが同じかどうかをテストします.
    if __name__ == '__main__':
        e1 = MyClass()
        e2 = MyClass()
        if e1 is e2:
            print(1)
        else:
            print(0)
    

      テスト済み、使用_new__メソッドとアクセラレータバージョンは同じインスタンスで、__を使用します.dict__別のインスタンス