創(chuàng)新互聯(lián)www.cdcxhl.cn八線動(dòng)態(tài)BGP香港云服務(wù)器提供商,新人活動(dòng)買多久送多久,劃算不套路!
本篇文章為大家展示了Python中什么是單例模式,代碼簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
python單例模式
單例模式是一種常用的軟件設(shè)計(jì)模式,在單例模式的核心結(jié)構(gòu)中,只包含一個(gè)被稱為單例類的特殊類。
通過(guò)單例模式可以保證系統(tǒng)中一個(gè)類只有一個(gè)實(shí)例,而且這個(gè)實(shí)例可以輕易被外界訪問(wèn),方便控制實(shí)例對(duì)象的個(gè)數(shù)以節(jié)約系統(tǒng)資源。
單例模式是解決一個(gè)系統(tǒng)中某個(gè)類的實(shí)例化對(duì)象有且只能有一個(gè)的最好解決方案。
單例模式的要點(diǎn)有三個(gè):
(1)某個(gè)類只能有一個(gè)實(shí)例。
(2)這個(gè)類必須自行創(chuàng)建其唯一實(shí)例。
(3)這個(gè)類必須自行向整個(gè)系統(tǒng)提供這個(gè)唯一實(shí)例。
在python中,單例模式有三種實(shí)現(xiàn)方式:
方法一,使用__new__方法
先定義一個(gè)類,類中定義__new__方法,然后將類的一個(gè)實(shí)例類綁定到類變量中。
如果類的_instance值為None,則說(shuō)明這個(gè)類還沒(méi)有被實(shí)例化過(guò),程序會(huì)自動(dòng)實(shí)例化一個(gè)類的實(shí)例,然后返回。
如果類的_instance值不為None,則程序會(huì)直接返回_instance。
代碼如下:
class Singleton(object): _instance = None def __init__(self): pass def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instance class MyClass(Singleton): a = 1
在上面的代碼中,我們將類的實(shí)例和一個(gè)類變量 _instance關(guān)聯(lián)起來(lái)。
如果 cls._instance為 None 則創(chuàng)建實(shí)例,否則直接返回cls._instance。
用上來(lái)定義的類實(shí)例化兩個(gè)對(duì)象:
cls1=MyClass() cls2=MyClass() print(id(cls1)) print(id(cls2)) print(cls1 == cls2) print(cls1 is cls2)
得到的結(jié)果
43606480 43606480 True True
方法二,使用decorator裝飾器
我們知道,裝飾器(decorator)可以動(dòng)態(tài)地修改一個(gè)類或函數(shù)的功能。
在這里使用裝飾器來(lái)裝飾某個(gè)類,使其只能生成一個(gè)實(shí)例,代碼如下:
def singleton(cls): instances={} def getinstance(*args,**kwargs): if cls not in instances: instances[cls]=cls(*args,**kwargs) return instances[cls] return getinstance @singleton class MyClass(object): a=1
在上面,我們定義了一個(gè)裝飾器singleton,它返回了一個(gè)內(nèi)部函數(shù)getinstance,該函數(shù)會(huì)判斷某個(gè)類是否在字典instances中,
如果不存在,則會(huì)將cls作為key,cls(*args, **kw)作為value存到instances中,否則,直接返回instances[cls]。
使用上面定義的類實(shí)例化兩個(gè)對(duì)象,比較兩個(gè)對(duì)象
cls1=MyClass() cls2=MyClass() print(id(cls1)) print(id(cls2)) print(cls1 == cls2) print(cls1 is cls2)
得到的結(jié)果為:
43672016 43672016 True True
方法三,使用元類(metaclass)
元類(metaclass)可以控制類的創(chuàng)建過(guò)程,它主要做三件事:
攔截類的創(chuàng)建 修改類的定義 返回修改后的類
用元類實(shí)現(xiàn)單例模式的代碼如下:
class Singleton(type): _inst = {} def __call__(self, *args, **kw): if self not in self._inst: self._inst[self] = super(Singleton, self).__call__(*args, **kw) return self._inst[self] class MyClass(metaclass=Singleton): def __init__(self): self.xx = 0 cls1=MyClass() cls2=MyClass() print(id(cls1)) print(id(cls2)) print(cls1 == cls2) print(cls1 is cls2)
得到的結(jié)果為:
43477984 43477984 True True
方法四,使用classmethod方法創(chuàng)建單例模式
class Foo: _instance = None def __init__(self): pass @classmethod def get_instance(cls): if cls._instance: return cls._instance else: obj=cls() cls._instance=obj return obj cls1=Foo.get_instance() # 實(shí)例化對(duì)象a1時(shí),沒(méi)有執(zhí)行Foo這個(gè)類的__init__方法,直接執(zhí)行Foo類的get_instance方法, 在這里cls代指的是Foo類。 # 前面把_instance賦值為None,所以直接執(zhí)行else中的語(yǔ)句,實(shí)例化一個(gè)obj對(duì)象, 然后把obj對(duì)象中的_instance方法賦值為obj對(duì)象本身,然后返回obj對(duì)象。 cls2=Foo.get_instance() # 實(shí)例化a1時(shí),Foo類中的_instance已經(jīng)被賦值為obj對(duì)象,所以再次執(zhí)行Foo中的get_instance方法時(shí), 是執(zhí)行if中的語(yǔ)句。 # 此時(shí)cls._instance就指的是obj對(duì)象,所以這里也返回obj這個(gè)對(duì)象。 print(id(cls1)) print(id(cls2)) print(cls1 == cls2) print(cls1 is cls2)
這種方法由于在實(shí)例化對(duì)象時(shí)要調(diào)用類中的get_instance方法,所以用的不多,知道即可。
特別聲明
Python的模塊是天然的單例模式,在一個(gè)py文件中,多次導(dǎo)入同一個(gè)模塊,這個(gè)模塊也只有在第一次的時(shí)候被導(dǎo)入,后續(xù)的該模塊導(dǎo)入語(yǔ)句都不會(huì)再執(zhí)行了。
上述內(nèi)容就是Python中什么是單例模式,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道。
文章題目:Python中什么是單例模式-創(chuàng)新互聯(lián)
標(biāo)題路徑:http://www.rwnh.cn/article28/pcccp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、企業(yè)網(wǎng)站制作、全網(wǎng)營(yíng)銷推廣、網(wǎng)站設(shè)計(jì)、App設(shè)計(jì)、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容
移動(dòng)網(wǎng)站建設(shè)知識(shí)