python 單例模式

單例模式

單例模式(Singleton Pattern)是一種常用的軟件設計模式把夸,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統(tǒng)中筐赔,某個類只能出現(xiàn)一個實例時萧落,單例對象就能派上用場珊随。

比如,某個服務器程序的配置信息存放在一個文件中污淋,客戶端通過一個 AppConfig 的類來讀取配置文件的信息顶滩。如果在程序運行期間,有很多地方都需要使用配置文件的內(nèi)容寸爆,也就是說礁鲁,很多地方都需要創(chuàng)建 AppConfig 對象的實例,這就導致系統(tǒng)中存在多個 AppConfig 的實例對象赁豆,而這樣會嚴重浪費內(nèi)存資源仅醇,尤其是在配置文件內(nèi)容很多的情況下。事實上魔种,類似 AppConfig 這樣的類析二,我們希望在程序運行期間只存在一個實例對象。

在 Python 中,我們可以用多種方法來實現(xiàn)單例模式:

使用模塊

使用__new__

使用裝飾器(decorator)

使用元類(metaclass)

使用模塊

其實叶摄,Python 的模塊就是天然的單例模式属韧,因為模塊在第一次導入時,會生成.pyc文件蛤吓,當?shù)诙螌霑r宵喂,就會直接加載.pyc文件,而不會再次執(zhí)行模塊代碼会傲。因此樊破,我們只需把相關的函數(shù)和數(shù)據(jù)定義在一個模塊中,就可以獲得一個單例對象了唆铐。如果我們真的想要一個單例類哲戚,可以考慮這樣做

# mysingleton.py

class My_Singleton(object):

???????? def foo(self):

??????????????? pass

my_singleton = My_Singleton()

將上面的代碼保存在文件mysingleton.py中,然后這樣使用

from mysingleton import my_singleton

my_singleton.foo()

使用__new__

為了使類只能出現(xiàn)一個實例艾岂,我們可以使用__new__來控制實例的創(chuàng)建過程顺少,代碼如下:

class Singleton(object):

_instance = None

??? ? def __new__(cls, *args, **kw):

??????????????????? if not cls._instance:

????????????????????????????? cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)

??????????????????? return cls._instance

class MyClass(Singleton):

a = 1

在上面的代碼中,我們將類的實例和一個類變量_instance關聯(lián)起來王浴,如果cls._instance為 None 則創(chuàng)建實例脆炎,否則直接返回cls._instance。

執(zhí)行情況如下:

>>> one = MyClass()

>>> two = MyClass()

>>> one == two

True

>>> one is two

True

>>> id(one), id(two)

(4303862608, 4303862608)


使用裝飾器

我們知道氓辣,裝飾器(decorator)可以動態(tài)地修改一個類或函數(shù)的功能秒裕。這里,我們也可以使用裝飾器來裝飾某個類钞啸,使其只能生成一個實例几蜻,代碼如下:

from functools import wraps

??????? def singleton(cls):

????????????????? instances = {}

????? @wraps(cls)

?????? def getinstance(*args, **kw):

?????????????????? if cls not in instances:

??????????????????????????? instances[cls] = cls(*args, **kw)

????????????????? ? ? ? ? ? return instances[cls]

??????????????? return getinstance

@singleton

class MyClass(object):

a = 1

在上面,我們定義了一個裝飾器singleton体斩,它返回了一個內(nèi)部函數(shù)getinstance梭稚,該函數(shù)會判斷某個類是否在字典instances中,如果不存在絮吵,則會將cls作為 key弧烤,cls(*args, **kw)作為 value 存到instances中,否則蹬敲,直接返回instances[cls]暇昂。

使用 metaclass

元類(metaclass)可以控制類的創(chuàng)建過程,它主要做三件事:

攔截類的創(chuàng)建

修改類的定義

返回修改后的類

使用元類實現(xiàn)單例模式的代碼如下:

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]

# Python2

class MyClass(object):

__metaclass__ = Singleton

# Python3

# class MyClass(metaclass=Singleton):

# pass

小結

Python 的模塊是天然的單例模式伴嗡,這在大部分情況下應該是夠用的急波,當然,我們也可以使用裝飾器闹究、元類等方法

參考資料

Creating a singleton in Python - Stack Overflow

深入淺出單實例Singleton設計模式 | 酷 殼

design patterns - Python’s use ofnewandinit? - Stack Overflow

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幔崖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赏寇,老刑警劉巖吉嫩,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嗅定,居然都是意外死亡自娩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進店門渠退,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忙迁,“玉大人,你說我怎么就攤上這事碎乃℃⑷樱” “怎么了?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵梅誓,是天一觀的道長恰梢。 經(jīng)常有香客問我,道長梗掰,這世上最難降的妖魔是什么嵌言? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮及穗,結果婚禮上摧茴,老公的妹妹穿的比我還像新娘。我一直安慰自己埂陆,他們只是感情好苛白,可當我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著猜惋,像睡著了一般丸氛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上著摔,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天,我揣著相機與錄音定续,去河邊找鬼谍咆。 笑死,一個胖子當著我的面吹牛私股,可吹牛的內(nèi)容都是我干的摹察。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼倡鲸,長吁一口氣:“原來是場噩夢啊……” “哼供嚎!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤克滴,失蹤者是張志新(化名)和其女友劉穎逼争,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劝赔,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡誓焦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了着帽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杂伟。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仍翰,靈堂內(nèi)的尸體忽然破棺而出赫粥,到底是詐尸還是另有隱情,我是刑警寧澤予借,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布傅是,位于F島的核電站,受9級特大地震影響蕾羊,放射性物質發(fā)生泄漏喧笔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一龟再、第九天 我趴在偏房一處隱蔽的房頂上張望书闸。 院中可真熱鬧,春花似錦利凑、人聲如沸浆劲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牌借。三九已至,卻和暖如春割按,著一層夾襖步出監(jiān)牢的瞬間膨报,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工适荣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留现柠,地道東北人。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓弛矛,卻偏偏與公主長得像够吩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丈氓,可洞房花燭夜當晚...
    茶點故事閱讀 43,566評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 單例模式(Singleton Pattern)是一種常用的軟件設計模式周循,該模式的主要目的是確保某一個類只有...
    佐卡ww閱讀 507評論 1 1
  • Python 中的單例模式 https://blog.csdn.net/l460133921/article/de...
    長風哥哥閱讀 396評論 1 1
  • 單例模式:即是一個類只有一個實例强法,即使創(chuàng)建了多個最終的結果還是會指向第一個創(chuàng)建的這個。 應用場景:1.python...
    _Him閱讀 283評論 0 0
  • 單例模式 Singleton 網(wǎng)上搜索python 單例模式湾笛,實現(xiàn)方式大致有一下幾種方式: 以模塊導入的方式 使用...
    snailpy閱讀 794評論 0 7
  • 昨天饮怯,我做了我的Pathway的第一個演講,演講題目《RESET》迄本。感覺怎么樣呢硕淑? 第一是意外,我寫了大概七分鐘的...
    呂蘭斌閱讀 362評論 0 0