實(shí)現(xiàn)單例模式的幾種方式

使用模塊

其實(shí)殖告,Python 的模塊就是天然的單例模式,因?yàn)槟K在第一次導(dǎo)入時雳锋,會生成 .pyc 文件黄绩,
當(dāng)?shù)诙螌?dǎo)入時,就會直接加載 .pyc 文件玷过,而不會再次執(zhí)行模塊代碼爽丹。
因此,我們只需把相關(guān)的函數(shù)和數(shù)據(jù)定義在一個模塊中辛蚊,就可以獲得一個單例對象了粤蝎。
如果我們真的想要一個單例類,可以考慮這樣做
1.創(chuàng)建test1.py文件,添加以下代碼

class Sington:
    def __init__(self,*args,**kwargs):
        self.name = args[0]
        self.age = kwargs["age"]

sington = Sington("nick",age=23)

2.創(chuàng)建test2.py文件,在test2.py文件里面導(dǎo)入test1.py文件里面的sington

from test1 import sington

print(sington.name)

使用裝飾器實(shí)現(xiàn)單例模式

代碼如下:代碼的思想就是在裝飾器里面放一個字典,這個字典會存放所有需要使用單例模式的類的映射.
當(dāng)不存在映射時,就創(chuàng)建一個對象進(jìn)去,存在就略過

from functools import wraps
def sington(cls):
    _instances = {}
    @wraps(cls)
    def wrapper(*args,**kwargs):
        if cls not in _instances:
            _instances[cls] = cls(*args,**kwargs)
        return _instances[cls]

    return wrapper


@sington
class Test:
    def __init__(self,*args,**kwargs):
        pass


test1 = Test()
test2 = Test()
print(id(test1) == id(test2))  # True

使用類的方式 (保證線程安全)

有陷阱的創(chuàng)建方式: 線程不安全

# 由于實(shí)例化對象的時候先調(diào)用__new__方法,再調(diào)用__init__方法,如果__init__出現(xiàn)耗時操作,比如數(shù)據(jù)庫連接
# 讀取文本之類的,就會造成多線程并發(fā)的情況下(時間片輪轉(zhuǎn))多個線程同時調(diào)用了instance方法.
# 就會造成多個對象出來,雖然最后一個執(zhí)行完的線程制造的對象會覆蓋掉之前創(chuàng)建的對象,
# 但依然是不安全的
import threading
import time
class Singleton(object):

    def __init__(self):
        time.sleep(1)

    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance



def task():
    obj = Singleton.instance()
    print(id(obj))

for i in range(10):
    t = threading.Thread(target=task)
    t.start()

解決方法:枷鎖

import time
import threading
class Singleton(object):
    _instance_lock = threading.Lock()

    def __init__(self):
        time.sleep(1)

    @classmethod
    def instance(cls, *args, **kwargs):
        with Singleton._instance_lock:
            if not hasattr(Singleton, "_instance"):
                Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance


def task():
    obj = Singleton.instance()
    print(id(obj))
list1 = list()
for i in range(10):
    t = threading.Thread(target=task)
    t.start()
    list1.append(t)
for i in list1:
    i.join()
obj = Singleton.instance()
print(obj)

方式三:基于new的線程安全

import threading
class Singleton(object):
    _instance_lock = threading.Lock()

    def __init__(self):
        pass


    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            with Singleton._instance_lock:
                if not hasattr(Singleton, "_instance"):
                    Singleton._instance = object.__new__(cls)  
        return Singleton._instance

obj1 = Singleton()
obj2 = Singleton()
print(obj1,obj2)

def task():
    obj = Singleton()
    print(obj)

for i in range(10):
    t = threading.Thread(target=task)
    t.start()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末袋马,一起剝皮案震驚了整個濱河市初澎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌虑凛,老刑警劉巖碑宴,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件软啼,死亡現(xiàn)場離奇詭異,居然都是意外死亡延柠,警方通過查閱死者的電腦和手機(jī)祸挪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贞间,“玉大人贿条,你說我怎么就攤上這事“竦” “怎么了闪唆?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長钓葫。 經(jīng)常有香客問我悄蕾,道長,這世上最難降的妖魔是什么础浮? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任帆调,我火速辦了婚禮,結(jié)果婚禮上豆同,老公的妹妹穿的比我還像新娘番刊。我一直安慰自己,他們只是感情好影锈,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布芹务。 她就那樣靜靜地躺著,像睡著了一般鸭廷。 火紅的嫁衣襯著肌膚如雪枣抱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天辆床,我揣著相機(jī)與錄音佳晶,去河邊找鬼。 笑死讼载,一個胖子當(dāng)著我的面吹牛轿秧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咨堤,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼菇篡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吱型?” 一聲冷哼從身側(cè)響起逸贾,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎津滞,沒想到半個月后铝侵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡触徐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年咪鲜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撞鹉。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡疟丙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鸟雏,到底是詐尸還是另有隱情享郊,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布孝鹊,位于F島的核電站炊琉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏又活。R本人自食惡果不足惜苔咪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柳骄。 院中可真熱鬧团赏,春花似錦、人聲如沸耐薯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽曲初。三九已至体谒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間复斥,已是汗流浹背营密。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留目锭,地道東北人评汰。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像痢虹,于是被迫代替她去往敵國和親被去。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

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