最近在寫乙個連線池,而連線池管理類不可避免的需要使用單例來保證所有使用者在取得連線時取到的一定是同乙個管理物件。故將此模式取來研究一番。
保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點 ——《設計模式》單例模式是全域性只有乙個訪問點,故對於乙個類來說,任何例項化後訪問到的都應該是同樣的物件。而也有另外一種變通思路,即訪問的不是同乙個物件,但其中資料是一樣的。對於第一種思路,可以在類新建的時候檢查是否之前已經被建立過。如果已經被建立過,則返回上次建立的物件,否則新建乙個物件。也可以定義乙個工廠來直接儲存乙個類的例項,客戶端向工廠請求時則返回此例項。對於第二種思路,可以將類中的屬性儲存在類中,每次新建類的時候將同樣的屬性賦予類,這樣,雖然每次返回的不是同乙個物件,但其屬性相同。
如上所述,方法
一、三基於第一種思路,方法二基於第二種思路。
在類的首次例項化時即儲存乙個全域性的物件,之後再次例項化時即直接返回此物件
class
singleton
(object):
def__new__
(cls):
ifnot hasattr(cls, '_instance'):
cls._instance = super(singleton,cls).__new__(cls)
return cls._instance
s2=singleton()
s3=singleton()
s4=singleton()
print id(s2),id(s3),id(s4)
結果為
>>>
49981368
49981368
49981368
注:使用此方法需要singleton類為新式類,即繼承了object類才可以使用super來找到父類
在類中保留乙個全域性的字典,用來儲存類中出現的屬性。在new時將例項中的__dict__
用此字典代替,使所有物件均使用此全域性字典來儲存屬性。
class
singleton2
(object):
_att={}
def__new__
(cls):
o = super(singleton2, cls).__new__(cls)
o.__dict__ = cls._att
return o
s2=singleton2()
s3=singleton2()
s2.a = 3
s3.c = 20
print id(s2),id(s3)
print s2.a,s2.c
print s3.a,s3.c
結果為
>>>
48998440
48998496320
320
注:此方法有侷限。因為如果在類中使用了__slots__
之後,則無法使用__dict__
來管理屬性。例如
class
singleton2
(object):
__slots__=['a','b']
_att={}
def__new__
(cls):
o = super(singleton2, cls).__new__(cls)
o.__dict__ = cls._att
return o
s2=singleton2()
s3=singleton2()
s2.a = 3
s3.c = 20
print id(s2),id(s3)
print s2.a,s2.c
print s3.a,s3.c
結果報錯
>>>
traceback (most recent call last):
file "c:\users\***\desktop\so.py", line
38, in
s2=singleton2()
file "c:\users\***\desktop\so.py", line
17, in __new__
o.__dict__ = cls._att
attributeerror: 'singleton2' object has no attribute '__dict__'
另:slots無法繼承。即帶有slots的類的子類中不再有slots限制。如果想繼承父類的slots,則需要在子類中也加入slots,此時限制的效果為父類與子類slots內容的並集。
另外借助工廠模式,定義乙個工廠類或方法。在此工廠中儲存乙個已經建立好的類例項,
class
t:pass
class
factory:
ins = t()
defcreatesingleton
(self):
return self.ins
if __name__ == '__main__':
s1=factory()
s2=factory()
os1=s1.createsingleton()
os2=s2.createsingleton()
print id(os1),id(os2)
結果為
>>>
30703064
30703064
Python 實現單例模式
encoding utf 8 print 方法1 方法1,實現 new 方法 並在將乙個類的例項繫結到類變數 instance上,如果cls.instance為none說明該類還沒有例項化過,例項化該類,並返回 如果cls.instance不為none,直接返回cls.instance class ...
python實現單例模式
單例模式,簡單來說,就是乙個類只能有乙個例項,並且能夠自行例項化向整個系統提供。例如檔案系統和任務管理器等。由此可見,單例模式的要點有三個 1.乙個類只能有乙個例項 2.它必須自行建立這個例項 3.它必須自行向整個系統提供這個例項 在python實現單例模式的方法總結起來有四種及其對應 如下 1.魔...
Python實現單例模式
語言是共通的,想要用不同語言實現單例模式,首先要清楚什麼是單例模式,單例模式即乙個類有且僅有乙個例項,那麼通過python怎麼實現乙個類只能有乙個例項呢。首先先建立乙個類,比如宇宙只有乙個地球 class earth pass a earth print id a b earth print id ...