【python】Python的單例模式

原文: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
相關文章
相關標籤/搜索