python実装の単一サブモード(説明付)


  • 一、metaclassによって
  • を実現する
    
    class Singleton(type):
        def __init__(self, name, bases, dct):
            super(Singleton, self).__init__(name, bases, dct)
            self.instance = None
    
        def __call__(self,*args,**kw):
            if self.instance is None:
                self.instance = super(Singleton, self).__call__(*args, **kw)
            return self.instance
    class A(object):
        __metaclass__ = Singleton
        def __init__(self):
            self.xx = 1
    A()
    

    注記:
       __metaclass__名前の通りclass Aのメタクラスであり、メタクラスとはその例がクラスである.したがって、Singletonの一例はclass Aである.ではA()はいったいどのような実行過程なのでしょうか.
      
  • 1)Singletonインスタンス化:Sinletonを暗黙的に呼び出す_new__メソッドはインスタンスを生成し、Singleton._を呼び出します.init__このインスタンスを初期化すると、初期化後にclass Aが生成されます.ここで,name,bases,dctはclass Aの定義における相関属性である.
  • 2)Aのインスタンス化はSingletonで定義されているため_call__,すなわち、Singletonのインスタンスは、関数のように呼び出すことができる.しかし、Singletonの例はclass Aであり、ルールに従って、Aをインスタンス化するときA()であり、解釈器はSingleton._を呼び出すことを選択する.call__(A._new_、A._init_)は呼び出されません.ではA._init__いつ呼び出されますか?
  • 3)Singleton._を実行中Call__場合、self.instance(A.instance)がNoneの場合、super(Singleton,self)が呼び出されます.call__,この関数ではA._が呼び出されます.init__,Aのインスタンスを初期化後にselfが存在する.Instance(A.instance)にあります.
  • これにより、Aのインスタンスが1つしかなく、A.instanceに格納される.元類は確かに少し回りますが、はっきりしたら、特定の時に大きな便利さをもたらすことができます.
  • 二、decoratorによって
  • を実現する
    
    class Singleton:
        """
        A non-thread-safe helper class to ease implementing singletons.
        This should be used as a decorator -- not a metaclass -- to the
        class that should be a singleton.
    
        The decorated class can define one `__init__` function that
        takes only the `self` argument. Other than that, there are
        no restrictions that apply to the decorated class.
    
        To get the singleton instance, use the `Instance` method. Trying
        to use `__call__` will result in a `TypeError` being raised.
    
        Limitations: The decorated class cannot be inherited from.
    
        """
    
        def __init__(self, decorated):
            self._decorated = decorated
    
        def Instance(self):
            """
            Returns the singleton instance. Upon its first call, it creates a
            new instance of the decorated class and calls its `__init__` method.
            On all subsequent calls, the already created instance is returned.
    
            """
            try:
                return self._instance
            except AttributeError:
                self._instance = self._decorated()
                return self._instance
    
        def __call__(self):
            raise TypeError('Singletons must be accessed through `Instance()`.')
    
        def __instancecheck__(self, inst):
            return isinstance(inst, self._decorated)
    
    
       @Singleton
       class Foo:
           def __init__(self):
               print 'Foo created'
    
       f = Foo() # Error, this isn't how you get the instance of a singleton
    
       f = Foo.Instance() # Good. Being explicit is in line with the Python Zen
       g = Foo.Instance() # Returns already created instance
    
       print f is g # True
    
  • 三、通過_new__
  • を実現します
    
    class Singleton(object):
        _instance = None
        def __new__(cls, *args, **kwargs):
            if not cls._instance:
                cls._instance = super(Singleton, cls).__new__(
                                    cls, *args, **kwargs)
            return cls._instance
    
    
    if __name__ == '__main__':
        s1=Singleton()
        s2=Singleton()
        if(id(s1)==id(s2)):
            print "Same"
        else:
            print "Different"
    

    ソースコードの一部は次のとおりです.
    http://stackoverflow.com/questions/42558/python-and-the-singleton-pattern
    http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python