單例模式(singleton pattern)是一種常用的軟體設計模式,該模式的主要目的是確保某乙個類只有乙個例項存在。當你希望在整個系統中,某個類只能出現乙個例項時,單例物件就能派上用場。
在 python 中,我們可以用多種方法來實現單例模式
其實,python 的模組就是天然的單例模式,因為模組在第一次匯入時,會生成 .pyc 檔案,當第二次匯入時,就會直接載入 .pyc 檔案,而不會再次執行模組**。因此,我們只需把相關的函式和資料定義在乙個模組中,就可以獲得乙個單例物件了。如果我們真的想要乙個單例類,可以考慮這樣做:
mysingleton.py
將上面的**儲存在檔案 mysingleton.py 中,要使用時,直接在其他檔案中匯入此檔案中的物件,這個物件即是單例模式的物件class
singleton
(object):
deffoo
(self)
:pass
singleton = singleton(
)
from a import singleton
def
singleton
(cls)
: instances =
def(
*args,
**kwargs)
:if cls not
in instances:
instances[cls]
= cls(
*args,
**kwargs)
return instances[cls]
@singleton
class
foo(
object):
pass
foo1 = foo(
)foo2 = foo(
(foo1 is foo2)
# true
classa:
pass
class
b(a)
:def
__new__
(cls)
("__new__方法被執行"
)return
super()
.__new__(cls)
def__init__
(self)
("__init__方法被執行")
b = b(
)# __new__方法被執行
# __init__方法被執行
我們比較兩個方法的引數,可以發現__new__方法是傳入類(cls),而__init__方法傳入類的例項化物件(self),而有意思的是,__new__方法返回的值就是乙個例項化物件(如果__new__方法返回none,則__init__方法不會被執行,並且返回值只能呼叫父類中的__new__方法,而不能呼叫毫無關係的類的__new__方法)。我們可以這麼理解它們之間的關係,__new__是開闢疆域的大將軍,而__init__是在這片疆域上辛勤勞作的小老百姓,只有__new__執行完後,開闢好疆域後,__init__才能工作。new 是真正建立例項物件的方法,所以重寫基類的new 方法,以此保證建立物件的時候只生成乙個例項
class
singleton
(object):
def__new__
(cls,
*args,
**kwargs):if
nothasattr
(cls,
'_instance'):
cls._instance =
super
(singleton, cls)
.__new__(cls,
*args,
**kwargs)
return cls._instance
class
foo(singleton)
:pass
foo1 = foo(
)foo2 = foo(
(foo1 is foo2)
# true
1.類由type建立,建立類時,type的__init__方法自動執行,類() 執行type的 __call__方法(類的__new__方法,類的__init__方法)2.物件由類建立,建立物件時,類的__init__方法自動執行,物件()執行類的call方法
元類是用於建立類物件的類,類物件建立例項物件時一定要呼叫call方法,因此在class
foo:
def__init__
(self)
:pass
def__call__
(self,
*args,
**kwargs)
:pass
obj = foo(
)# 執行type的 __call__ 方法,呼叫 foo類(是type的物件)的 __new__方法,用於建立物件,然後呼叫 foo類(是type的物件)的 __init__方法,用於對物件初始化。
obj(
)# 執行foo的 __call__ 方法
呼叫call時候保證始終只建立乙個例項即可,type是python的元類
當我們實現單例時,為了保證執行緒安全需要在內部加入鎖class
singleton
(type):
def__call__
(cls,
*args,
**kwargs):if
nothasattr
(cls,
'_instance'):
cls._instance =
super
(singleton, cls)
.__call__(
*args,
**kwargs)
return cls._instance
# python2
class
foo(
object):
__metaclass__ = singleton
# python3
class
foo(metaclass=singleton)
:pass
foo1 = foo(
)foo2 = foo(
(foo1 is foo2)
# true
我們知道,當我們例項化乙個物件時,是先執行了類的__new__方法(我們沒寫時,預設呼叫object.new),例項化物件;然後再執行類的__init__方法,對這個物件進行初始化,所有我們可以基於這個,實現單例模式
參考:import threading
class
singleton
(object):
_instance_lock = threading.lock(
)def
__init__
(self)
:pass
def__new__
(cls,
*args,
**kwargs):if
nothasattr
(singleton,
"_instance"):
with singleton._instance_lock:
ifnot
hasattr
(singleton,
"_instance"):
singleton._instance =
object
.__new__(cls)
return singleton._instance
obj1 = singleton(
)obj2 = singleton(
(obj1,obj2)
deftask
(arg)
: obj = singleton(
(obj)
for i in
range(10
):t = threading.thread(target=task,args=
[i,]
) t.start(
)
Python如何實現單例模式
單例模式 singleton pattern 是一種常用的軟體設計模式,該模式的主要目的是確保某乙個類只有乙個例項存在。當你希望在整個系統中,某個類只能出現乙個例項時,單例物件就能派上用場。單例設計模式介紹 參考 實現方法 將需要實現的單例功能放到乙個.py 檔案中 實現原理 python 的模組就...
python實現單例模式
最近在寫乙個連線池,而連線池管理類不可避免的需要使用單例來保證所有使用者在取得連線時取到的一定是同乙個管理物件。故將此模式取來研究一番。保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點 設計模式 單例模式是全域性只有乙個訪問點,故對於乙個類來說,任何例項化後訪問到的都應該是同樣的物件。而也有另...
Python 實現單例模式
encoding utf 8 print 方法1 方法1,實現 new 方法 並在將乙個類的例項繫結到類變數 instance上,如果cls.instance為none說明該類還沒有例項化過,例項化該類,並返回 如果cls.instance不為none,直接返回cls.instance class ...