Python-単例モード-一度だけ初期化

2063 ワード

##単例モードは一度だけ初期化
単例モード作成の原理は,プライベートクラス属性の性質を借りたものであり,プライベートクラス属性が直接クラス外で変更されることはできないことを知っているので,プライベートクラス属性の状態を条件としてクラス内メソッドの呼び出しを制御する
方法1:
次のコードの_species担当制御_new__メソッドでは、インスタンス・オブジェクトが1回しか作成できないことを保証し、同じデータ・メモリの場所を指す複数のオブジェクトを作成します.
__first_Init担当制御_init__メソッドでは、再作成したオブジェクトが初期化された内容を変更できないことを保証します.
class Animal(object):

    __species = None
    __first_init = True
    
    def __new__(cls, *args, **kwargs):
        if cls.__species == None:
            cls.__species = object.__new__(cls)
        return cls.__species

    def __init__(self,name):
        print("-----init----")
        if self.__first_init:
            self.name = name
            self.__class__.__first_init = False
            #    Animal.__first_init = False

    def __str__(self):
        return "-------str---%s" %self.name


if __name__ == '__main__':
    dog = Animal('  ')
    print(dog)
    print(id(dog))  
    dog2 = Animal('  ')
    print(dog)
    print(id(dog2))

    :
-----init----
-------str---  
139764904013104
-----init----
-------str---  
139764904013104


  new      return,                __new__        

実行結果から分かるように、2回作成されたインスタンスオブジェクトは、同じid、すなわち、単例モードで2回目に作成されたインスタンスオブジェクトdog 2「金毛」を作成し、作成に成功せず、初めて作成されたインスタンスオブジェクトdog「二哈」、すなわち初期化されたインスタンスオブジェクトdog
方法2:
import functools

def singleton(cls):
    _instances = {}
    @functools.wraps(cls)
    def get_instance(*args, **kwargs):
        if cls not in _instances:
            _instances[cls] = cls(*args, **kwargs)
        return _instances[cls]
	 return get_instance


@singleton
class Animal:

    def __init__(self, name):
        print("-----init----")
        self.name = name

    def __str__(self):
        return "-------str---%s" % self.name


if __name__ == '__main__':
    dog = Animal('  ')
    print(dog)
    print(id(dog))
    dog2 = Animal('  ')
    print(dog)
    print(id(dog2))

実行結果:------init--------str-二哈4327353816------str-二哈4327353816