單例模式是一種常用的軟體設計模式,屬於建立型模式。單例模式的核心結構就是系統中乙個類只有乙個例項,保證了在程式的不同位置都可以且僅可以取到同乙個物件例項。
應用場景:
1.單例模式廣泛應用於各種開發場景:
遊戲中需要有「場景管理器」這樣一種東西,用來管理遊戲場景的切換、資源載入、網路連線等等任務。這個管理器需要有多種方法和屬性,在**中很多地方會被呼叫,且被呼叫的必須是同乙個管理器,否則既容易產生衝突,也會浪費資源
2.一些資源管理器常常設計成單例模式:
在計算機系統中,需要管理的資源包括軟體外部資源,譬如每台計算機可以有若干個印表機,但只能有乙個printer spooler,以避免兩個印表機作業同時輸出到印表機中。每台計算機可以有若干傳真機卡,但是只應該有乙個軟體負責管理傳真卡,以避免乙個通訊埠同時被兩個請求同時呼叫。
需要管理的資源包括軟體內部資源,譬如,大多數的軟體都有乙個(甚至多個)屬性(properties)檔案存放系統配置。這樣的系統應當由乙個物件來管理乙個屬性檔案。
1、常用的單例模式
classsingleton(object):
_instance =none
def__new__(cls, *args, **kwargs):
ifnot cls._instance
: cls.
_instance = super(singleton, cls).__new__(cls)
return cls._instance
s1 =singleton()
s2 =singleton()
print(s1 is s2) #
true
屬性共用的單例
"""上面的第一種寫法,雖然建立的是同乙個例項,
但是屬性是不共用的,因為每次__init__都會重新設定
"""class
singleton(object):
_instance =none
def__new__(cls, *args, **kwargs):
ifnot
cls._instance:
cls._instance = super(singleton, cls).__new__
(cls)
return
cls._instance
def__init__
(self, name, age):
self.name =name
self.age =age
s1 = singleton(name="
小明", age=18)
print(s1.name, s1.age) #
小明 18
s2 = singleton(name="
小紅", age=17) #
這裡相當於是重新賦值了name和age,之後的name age都是這個值
print(s2.name, s2.age) #
小紅 17
print(s1 is s2) #
true
"""因此想要屬性也共用,__init__也需要處理
"""class
singleton(object):
_instance =none
_initialized =false
def__new__(cls, *args, **kwargs):
ifnot
cls._instance:
cls._instance = super(singleton, cls).__new__
(cls)
return
cls._instance
def__init__
(self, name, age):
ifnot
singleton._initialized:
self.name =name
self.age =age
singleton._initialized =true
s1 = singleton(name="
小明", age=18)
print(s1.name, s1.age) #
小明 18
s2 = singleton(name="
小紅", age=17)
print(s2.name, s2.age) #
小明 18
print(s1 is s2) #
true
加鎖的單例
importtime
import
threading
class
singleton(object):
lock = threading.rlock() #
定義一把鎖
_instance =none
def__new__(cls, *args, **kwargs):
ifcls._instance:
return cls._instance #
如果之前例項化過,沒必要再次例項化,因為都是同乙個例項
with cls.lock:
#避免當執行緒沒有返回例項前,另乙個執行緒也進來了,導致出現不止乙個例項
ifnot
cls._instance:
cls._instance = super(singleton, cls).__new__
(cls)
return
cls._instance
deftask(arg):
obj =singleton()
(obj)
for i in range(10):
t = threading.thread(target=task,args=(i,))
t.start()
time.sleep(10)
obj = singleton()
2、函式單例裝飾器
defsingleton(cls):
_instance ={}
def _singleton(*args, **kwargs):
if cls not
in_instance:
_instance[cls] = cls(*args, **kwargs)
return
_instance[cls]
return
_singleton
@singleton
class
a():
def__init__
(self, name):
self.name =name
a1 = a("
ming")
print(a1.name) #
ming
a2 = a("
dong")
print(a2.name) #
ming
3、類單例裝飾器
classsingleton(object):
def__init__
(self, cls):
self._cls =cls
self._instance ={}
def__call__(self, *args, **kwargs):
if self._cls not
inself._instance:
self._instance[self._cls] = self._cls(*args, **kwargs)
return
self._instance[self._cls]
@singleton
class
a():
def__init__
(self, name):
self.name =name
a1 = a("
ming")
print(a1.name) #
ming
a2 = a("
dong")
print(a2.name) #
ming
4、使用 metaclass 實現單例模式
classsingleton(type):
_instance ={}
def__call__(cls, *args, **kwargs):
if cls not
incls._instance:
cls._instance[cls] = super(singleton, cls).__call__(*args, **kwargs)
return
cls._instance[cls]
class a(metaclass=singleton):
def__init__
(self, name):
self.name =name
a1 = a("
ming")
print(a1.name) #
ming
a2 = a("
dong")
print(a2.name) #
ming
python之單例模式
單例模式 1.new 方法的使用 new 是乙個由object基類提供的內建的靜態方法,主要作用有兩個 在使用類名 建立物件時,python直譯器首先會呼叫 new 方法,為物件分配記憶體空間 python的直譯器獲得物件的引用後,將引用作為第乙個引數,傳遞給 init 方法 重寫 new 方法的 ...
Python設計模式之單例模式
站 物件 印表機 物件 使用類名 建立物件時,python 的直譯器首先 會 呼叫 new 方法為物件 分配空間。new 是乙個 由object基類提供的內建的靜態方法,主要作用有兩個 python 的直譯器獲得物件的 引用 後,將引用作為 第乙個引數,傳遞給 init 方法。重寫 new 方法 的...
python設計模式之單例模式
單例模式是一種建立型設計模式,它確保乙個類有且只有乙個特定型別的物件,並提供全域性訪問點。其意圖為 簡單理解 單例即為單個例項,也就是每次例項化建立物件時獲得的都是同乙個物件,當然同乙個物件的屬性都是相同的,方法也是相同的,位址也是相同的,這樣給我們帶來的好處就是可以避免消耗過多的記憶體或cpu資源...