原文:http://blog.csdn.net/ghostfromheaven/article/details/7671853python
單例模式:保證一個類僅有一個實例,並提供一個訪問他的全局訪問點。安全
實現某個類只有一個實例的途徑:多線程
1,讓一個全局變量使得一個對象被訪問,可是他不能防止外部實例化多個對象。spa
2,讓類自身保存他的惟一實例,這個類能夠保證沒有其餘實例能夠被建立。.net
多線程時的單例模式:加鎖-雙重鎖定線程
餓漢式單例類:在類被加載時就將本身實例化(靜態初始化)。其優勢是躲避了多線程訪問的安全性問題,缺點是提早佔用系統資源。code
懶漢式單例類:在第一次被引用時,纔將本身實例化。避免開始時佔用系統資源,可是有多線程訪問安全性問題。對象
下面是實現單例模式的4中方法:blog
1 #-*- encoding=utf-8 -*- 2 print '----------------------方法1--------------------------' 3 #方法1,實現__new__方法 4 #並在將一個類的實例綁定到類變量_instance上, 5 #若是cls._instance爲None說明該類尚未實例化過,實例化該類,並返回 6 #若是cls._instance不爲None,直接返回cls._instance 7 class Singleton(object): 8 def __new__(cls, *args, **kw): 9 if not hasattr(cls, '_instance'): 10 orig = super(Singleton, cls) 11 cls._instance = orig.__new__(cls, *args, **kw) 12 return cls._instance 13 14 class MyClass(Singleton): 15 a = 1 16 17 one = MyClass() 18 two = MyClass() 19 20 two.a = 3 21 print one.a 22 #3 23 #one和two徹底相同,能夠用id(), ==, is檢測 24 print id(one) 25 #29097904 26 print id(two) 27 #29097904 28 print one == two 29 #True 30 print one is two 31 #True 32 33 print '----------------------方法2--------------------------' 34 #方法2,共享屬性;所謂單例就是全部引用(實例、對象)擁有相同的狀態(屬性)和行爲(方法) 35 #同一個類的全部實例自然擁有相同的行爲(方法), 36 #只須要保證同一個類的全部實例具備相同的狀態(屬性)便可 37 #全部實例共享屬性的最簡單最直接的方法就是__dict__屬性指向(引用)同一個字典(dict) 38 #可參看:http://code.activestate.com/recipes/66531/ 39 class Borg(object): 40 _state = {} 41 def __new__(cls, *args, **kw): 42 ob = super(Borg, cls).__new__(cls, *args, **kw) 43 ob.__dict__ = cls._state 44 return ob 45 46 class MyClass2(Borg): 47 a = 1 48 49 one = MyClass2() 50 two = MyClass2() 51 52 #one和two是兩個不一樣的對象,id, ==, is對比結果可看出 53 two.a = 3 54 print one.a 55 #3 56 print id(one) 57 #28873680 58 print id(two) 59 #28873712 60 print one == two 61 #False 62 print one is two 63 #False 64 #可是one和two具備相同的(同一個__dict__屬性),見: 65 print id(one.__dict__) 66 #30104000 67 print id(two.__dict__) 68 #30104000 69 70 print '----------------------方法3--------------------------' 71 #方法3:本質上是方法1的升級(或者說高級)版 72 #使用__metaclass__(元類)的高級python用法 73 class Singleton2(type): 74 def __init__(cls, name, bases, dict): 75 super(Singleton2, cls).__init__(name, bases, dict) 76 cls._instance = None 77 def __call__(cls, *args, **kw): 78 if cls._instance is None: 79 cls._instance = super(Singleton2, cls).__call__(*args, **kw) 80 return cls._instance 81 82 class MyClass3(object): 83 __metaclass__ = Singleton2 84 85 one = MyClass3() 86 two = MyClass3() 87 88 two.a = 3 89 print one.a 90 #3 91 print id(one) 92 #31495472 93 print id(two) 94 #31495472 95 print one == two 96 #True 97 print one is two 98 #True 99 100 print '----------------------方法4--------------------------' 101 #方法4:也是方法1的升級(高級)版本, 102 #使用裝飾器(decorator), 103 #這是一種更pythonic,更elegant的方法, 104 #單例類自己根本不知道本身是單例的,由於他自己(本身的代碼)並非單例的 105 def singleton(cls, *args, **kw): 106 instances = {} 107 def _singleton(): 108 if cls not in instances: 109 instances[cls] = cls(*args, **kw) 110 return instances[cls] 111 return _singleton 112 113 @singleton 114 class MyClass4(object): 115 a = 1 116 def __init__(self, x=0): 117 self.x = x 118 119 one = MyClass4() 120 two = MyClass4() 121 122 two.a = 3 123 print one.a 124 #3 125 print id(one) 126 #29660784 127 print id(two) 128 #29660784 129 print one == two 130 #True 131 print one is two 132 #True 133 one.x = 1 134 print one.x 135 #1 136 print two.x 137 #1