目錄
-
python 單例模式
- 1、什么是單例模式
- 2、__new__方法實現
- 3、裝飾器實現
- 4、模塊實現
- 5、共享屬性實現
- 6、元類實現
python 單例模式
1、什么是單例模式
單例模式(Singleton Pattern)是一種常用的軟件設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統中,某個類只能出現一個實例時,單例對象就能派上用場。
比如,某個服務器程序的配置信息存放在一個文件中,客戶端通過一個 AppConfig 的類來讀取配置文件的信息。如果在程序運行期間,有很多地方都需要使用配置文件的內容,也就是說,很多地方都需要創建 AppConfig 對象的實例,這就導致系統中存在多個 AppConfig 的實例對象,而這樣會嚴重浪費內存資源,尤其是在配置文件內容很多的情況下。事實上,類似 AppConfig 這樣的類,我們希望在程序運行期間只存在一個實例對象。
在 Python 中,我們可以用多種方法來實現單例模式。
2、__new__方法實現
首先,我最推薦使用__new__方法來實現單例模式,因為我覺得這種方法是最容易理解的。我們知道__new__方法是類在實例化過程中調用的一個方法,該方法還要在__init__方法之前調用,用于創建類的實例化對象。那么我們是不是可以重寫__new__ ,讓他判斷是否已經調用過該方法了,如果已經調用過了,直接返回上次實例化的對象,那么該類不就一直只存在一個實例化對象了嗎,就實現了單例,例子如下。
class Singleton(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
rerurn cls._instance
class A(Singleton):
pass
# 類A即為單例類
3、裝飾器實現
我們可以寫一個裝飾器,來裝飾我們需要指定的單例類,這樣也可以實現。
def singleton(cls):
instance = {}
def wapper():
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
return instance[cls]
return wapper
@singleton
class C:
pass
# 類C即為單例類
4、模塊實現
我們知道,在python中,我們可以自己寫一個py文件,里面的類或者方法就可以通過模塊導入。在python中,用模塊導入的類就是一個天然的單例。
# 作為Python模塊時是天然的單例模式
#創建一個sington.py文件,內容如下:
class Singleton(object):
def foo(self):
pass
mysington = Singleton()
# 運用
from sington import mysington
5、共享屬性實現
創建實例時把所有實例的__dict__指向同一個字典,這樣它們都具有相同的屬性和方法(類的__dict__存儲對象屬性)
class Singleton(object):
_state = {}
def __new__(cls, *args, **kwargs):
ob = super(Singleton,cls).__new__(cls, *args, **kwargs)
ob.__dict__ = cls._state
return ob
class B(Singleton):
pass
# 類B即為單例類
6、元類實現
最后一種方法使用元類實現單例模式,這種方法比較不容易理解,首先需要理解元類是什么,這里就不展開細講了,有興趣的同學可以自行學習元類的用法。
class Singleton(type):
_instacne = {}
def __call__(cls,*args,**kwargs):
if cls not in cls._instance:
cls._instances[cls] = super(Singleton, cls).__call__(*args,**kwargs)
#以cls為key,cls(*args, **kwargs) 為值放入盛放單例的字典
return cls._instance[cls]
class MyClass(metaclass=Singleton):
pass
#MyClass即為單例類
好啦,單例模式的實現方法大致就是以上幾種了,大家可以學習學習。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
