單例是一種設計模式
,應用該模式的類只會生成乙個例項。
單例模式保證了在程式的不同位置都可以且僅可以取到同乙個物件例項:如果例項不存在,會建立乙個例項;如果已存在就會返回這個例項。因為單例是乙個類,所以你也可以為其提供相應的操作方法,以便於對這個例項進行管理。
以下是實現方法索引:
使用__new__
方法在創造例項時進行干預,達到實現單例模式的目的。
class
single
(object):
_instance =
none
def__new__
(cls,
*args,
**kw)
:if cls._instance is
none
: cls._instance =
object
.__new__(cls,
*args,
**kw)
return cls._instance
def__init__
(self)
:pass
single1 = single(
)single2 = single(
)print(id
(single1)
==id
(single2)
)
在理解到new的應用後,理解單例就不難了,這裡使用了
_instance =
none
來存放例項,如果 _instance 為 none,則新建例項,否則直接返回 _instance 存放的例項。
以下是實現**:
def
singleton
(cls)
: _instance =
definner()
:if cls not
in _instance:
_instance[cls]
= cls(
)return _instance[cls]
return inner
@singleton
class
cls(
object):
def__init__
(self)
:pass
cls1 = cls(
)cls2 = cls(
)print(id
(cls1)
==id
(cls2)
)
輸出結果:
true
在 python 中,id 關鍵字可用來檢視物件在記憶體中的存放位置,這裡 cls1 和 cls2 的 id 值相同,說明他們指向了同乙個物件。
關於裝飾器的知識,有不明白的同學可以檢視之前的文章 【程式設計課堂】裝飾器** 或者使用搜尋引擎再學習一遍。**中比較巧妙的一點是:
_instance =
使用不可變的類位址作為鍵,其實例作為值,每次創造例項時,首先檢視該類是否存在例項,存在的話直接返回該例項即可,否則新建乙個例項並存放在字典中。
**:
class
singleton
(object):
def__init__
(self, cls)
: self._cls = cls
self._instance =
def__call__
(self)
:if self._cls not
in self._instance:
self._instance[self._cls]
= self._cls(
)return self._instance[self._cls]
@singleton
class
cls2
(object):
def__init__
(self)
:pass
cls1 = cls2(
)cls2 = cls2(
)print(id
(cls1)
==id
(cls2)
)
同時,由於是面對物件的,這裡還可以這麼用
class
cls3()
:pass
cls3 = singleton(cls3)
cls3 = cls3(
)cls4 = cls3(
)print(id
(cls3)
==id
(cls4)
)
使用 類裝飾器實現單例的原理和 函式裝飾器 實現的原理相似,理解了上文,再理解這裡應該不難。
同樣,我們在類的建立時進行干預,從而達到實現單例的目的。
在實現單例之前,需要了解使用 type 創造類的方法,**如下:
def
func
(self)
:print
("do sth"
)klass =
type
("klass",(
),)c = klass(
)c.func(
)
以上,我們使用 type 創造了乙個類出來。這裡的知識是 mataclass 實現單例的基礎。
class
singleton
(type):
_instances =
def__call__
(cls,
*args,
**kwargs)
:if cls not
in cls._instances:
cls._instances[cls]
=super
(singleton, cls)
.__call__(
*args,
**kwargs)
return cls._instances[cls]
class
cls4
(metaclass=singleton)
:pass
cls1 = cls4(
)cls2 = cls4(
)print(id
(cls1)
==id
(cls2)
)
這裡,我們將 metaclass 指向 singleton 類,讓 singleton 中的 type 來創造新的 cls4 例項。
本文雖然是講單例模式,但在實現單例模式的過程中,涉及到了蠻多高階 python 語法,包括裝飾器、元類、new、type 甚至 super 等等。對於新手同學可能難以理解,其實在工程專案中並不需要你掌握的面面俱到,掌握其中一種,剩下的作為了解即可。
Python設計模式之單例模式
站 物件 印表機 物件 使用類名 建立物件時,python 的直譯器首先 會 呼叫 new 方法為物件 分配空間。new 是乙個 由object基類提供的內建的靜態方法,主要作用有兩個 python 的直譯器獲得物件的 引用 後,將引用作為 第乙個引數,傳遞給 init 方法。重寫 new 方法 的...
python設計模式之單例模式
單例模式是一種建立型設計模式,它確保乙個類有且只有乙個特定型別的物件,並提供全域性訪問點。其意圖為 簡單理解 單例即為單個例項,也就是每次例項化建立物件時獲得的都是同乙個物件,當然同乙個物件的屬性都是相同的,方法也是相同的,位址也是相同的,這樣給我們帶來的好處就是可以避免消耗過多的記憶體或cpu資源...
Python設計模式之單例模式
單例模式屬於建立型模式,它提供了一種建立物件的最佳方式。這種模式涉及到乙個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。單例模式是獲取全域性狀態的一種相當好的方法,但這也是對於單例模式的主要批評之處,因為在...