GeorgeYang'Blog

my technology blog

Python单例模式的4种实现方法

阅读:219 创建时间:15-12-30 21:21:41 tags:

方法一:

 class Singleton(type):  
     def __init__(cls, name, bases, dict):  
     super(Singleton, cls).__init__(name, bases, dict)  
     cls.instance = None

     def __call__(cls, *args, **kw):  
     if cls.instance is None:  
         cls.instance = super(Singleton, cls).__call__(*args, **kw)  
         return cls.instance

 class MyClass(object):  
     __metaclass__ = Singleton

 print MyClass()  
 print MyClass()

方法二:使用装饰器(decorator)

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

 @singleton  
 class MyClass(object):  
     a = 1  
     def __init__(self, x=0):  
         self.x = x

 one = MyClass()  
 two = MyClass()

 two.a = 3  
 print one.a  
 #3  
 print id(one)  
 #29660784  
 print id(two)  
 #29660784  
 print one == two  
 #True  
 print one is two  
 #True  
 one.x = 1  
 print one.x  
 #1  
 print two.x

方法三:使用metaclass元类来实现

 class Singleton2(type):  
     def __init__(cls, name, bases, dict):  
         super(Singleton2, cls).__init__(name, bases, dict)  
         cls._instance = None  
     def __call__(cls, *args, **kw):  
         if cls._instance is None:  
             cls._instance = super(Singleton2, cls).__call__(*args, **kw)  
         return cls._instance

 class MyClass(object):  
     __metaclass__ = Singleton2

 one = MyClass()  
 two = MyClass()

 two.a = 3  
 print one.a  
 #3  
 print id(one)  
 #31495472  
 print id(two)  
 #31495472  
 print one == two  
 #True  
 print one is two  
 #True

方法四:通过共享属性来实现,所谓共享属性,最简单直观的方法就是通过dict属性指向同一个字典dict

 class Singleton(object): 
     def new(cls,*args,*<em>kw): 
         if not hasattr(cls, '_sgl'): 
             cls._sgl = super(Singleton, cls).new(cls,</em>args,**kw) 
         return cls._sgl 
 if name =='main': 
     a = Singleton() 
     b = Singleton() 
     print id(a) 
     print id(b)
     #输出的id相同