400-650-7353
您所在的位置:首頁(yè) > IT干貨資料 > python > 【Python基礎(chǔ)知識(shí)】單例模式

【Python基礎(chǔ)知識(shí)】單例模式

  • 發(fā)布: python培訓(xùn)
  • 來(lái)源:python培訓(xùn)問(wèn)答
  • 2021-03-22 16:22:06
  • 閱讀()
  • 分享
  • 手機(jī)端入口

單例模式是保證一個(gè)類(lèi)僅有一個(gè)實(shí)例的設(shè)計(jì)模式。Windows中的任務(wù)管理器就是一個(gè)典型的單例模式軟件。Windows任務(wù)管理器如圖所示。

Windows任務(wù)管理器

Windows任務(wù)管理器只能打開(kāi)一個(gè),即使用戶(hù)重復(fù)打開(kāi),也只能獲得一個(gè)實(shí)例,這不同于Word等軟件可以打開(kāi)多個(gè)實(shí)例。這是因?yàn)槿绻?個(gè)窗口同時(shí)都能結(jié)束進(jìn)程,那么在窗口A中結(jié)束了某進(jìn)程,而在窗口B中該進(jìn)程還保留著;反之,在窗口B中結(jié)束了某進(jìn)程,而在窗口A中該進(jìn)程還保留著。這樣就會(huì)造成沖突,導(dǎo)致系統(tǒng)崩潰。

定義單例類(lèi)的語(yǔ)法格式如下:

class 類(lèi)名(object):

def __new__(cls, *args, **kwargs):

if not hasattr(cls, '_instance'):

# 第一種方式

cls._instance = object.__new__(cls)

# 第二種方式

# cls._instance = super(類(lèi)名, cls).__new__(cls)

return cls._instance

創(chuàng)建的單例類(lèi)繼承了object類(lèi)。類(lèi)中定義了一個(gè)魔法方法__new__(),__new__()方法是創(chuàng)建實(shí)例時(shí)調(diào)用的方法,因此,常說(shuō)的創(chuàng)建一個(gè)實(shí)例,其實(shí)就是使用這個(gè)方法創(chuàng)建的。在__new__()方法中,第一個(gè)參數(shù)為cls,說(shuō)明這是一個(gè)類(lèi)方法,后面兩個(gè)參數(shù)分別為*args和**kwargs。用這個(gè)方法來(lái)創(chuàng)建唯一實(shí)例。__new__()方法中,采用if語(yǔ)句判斷當(dāng)前類(lèi)的實(shí)例是否存在,如果不存在,那么需要先創(chuàng)建實(shí)例,再返回當(dāng)前類(lèi)的實(shí)例;如果存在,那么直接返回當(dāng)前類(lèi)的實(shí)例。可以采用兩種方式來(lái)創(chuàng)建實(shí)例,第一種方式是父類(lèi)object調(diào)用魔法方法__new__(),參數(shù)為當(dāng)前類(lèi)本身;第二種是用super()方法,指定調(diào)用當(dāng)前類(lèi)父類(lèi)的__new__()方法。

【Python基礎(chǔ)知識(shí)】單例模式

下面是一個(gè)單例類(lèi)的示例。先編寫(xiě)一個(gè)Singleton類(lèi),代碼如下:

  1. class Singleton(object): 
  2.     def __new__(cls, *args, **kwargs): 
  3.         if not hasattr(cls'_instance'): 
  4.             cls._instance = object.__new__(cls
  5.             # cls._instance = super(Singleton, cls).__new__(cls) 
  6.         return cls._instance 

再創(chuàng)建Singleton類(lèi)的兩個(gè)實(shí)例,代碼如下:

  1. s1 = Singleton() 
  2. s2 = Singleton() 

最后通過(guò)id()函數(shù)生成兩個(gè)實(shí)例的內(nèi)存地址,從而判斷Singleton類(lèi)是不是單例類(lèi),代碼如下:

  1. print('s1的地址:{},s2的地址:{}'.format(id(s1), id(s2))) 

運(yùn)行結(jié)果:

  1. s1的地址:31244920,s2的地址:31244920 

由運(yùn)行結(jié)果可知,這兩個(gè)實(shí)例的內(nèi)存地址一致,說(shuō)明是同一個(gè)實(shí)例,即生成的是單一實(shí)例,也就是說(shuō)s1和s2其實(shí)是這一個(gè)實(shí)例的不同名稱(chēng)而已,因此,Singleton類(lèi)是單例類(lèi)。

在上述示例的基礎(chǔ)上,先創(chuàng)建一個(gè)Mother類(lèi)繼承Singleton類(lèi),類(lèi)中包含實(shí)例屬性msg表示菜信息,實(shí)例方法get_food()用于接收并拼接菜信息msg,實(shí)例方法food()用于打印菜信息msg:

  1. class Mother(Singleton):   # 繼承Singleton類(lèi) 
  2.     def __init__(self, msg=''): 
  3.         self.msg = msg 
  4.     def get_food(self, new_food): 
  5.         self.msg += new_food 
  6.     def food(self): 
  7.         print('做菜:'self.msg) 

再創(chuàng)建Mother類(lèi)的兩個(gè)實(shí)例,并分別調(diào)用get_food()方法將菜信息作為參數(shù)進(jìn)行傳遞,代碼如下:

  1. mother1 = Mother() 
  2. mother2 = Mother() 
  3. mother1.get_food('西紅柿'
  4. mother2.get_food('雞蛋'

最后分別打印這兩個(gè)實(shí)例的內(nèi)存地址,并調(diào)用food()方法打印菜信息,代碼如下:

  1. print('兒子的媽媽id:', id(mother1)) 
  2. mother1.food() 
  3. print('女兒的媽媽id:', id(mother2)) 
  4. mother2.food() 

運(yùn)行結(jié)果:

  1. 兒子的媽媽id: 5758896 
  2. 做菜: 西紅柿雞蛋 
  3. 女兒的媽媽id: 5758896 
  4. 做菜: 西紅柿雞蛋 

由于Monther類(lèi)繼承了Singleton類(lèi),因此,實(shí)例mother1和mother2指向的是同一個(gè)內(nèi)存地址,兩次調(diào)用get_food()方法,參數(shù)中的字符串會(huì)拼接在一起,在調(diào)用food()方法時(shí),打印結(jié)果都是拼接后的“西紅柿雞蛋”。

如果在創(chuàng)建Mother類(lèi)時(shí)不繼承Singleton類(lèi),那么運(yùn)行結(jié)果是否發(fā)生改變呢?只修改定義Mother類(lèi)的第一行代碼,其余代碼不變,修改的代碼如下:

  1. class Mother(): 

運(yùn)行結(jié)果:

  1. 兒子的媽媽id: 169246848 
  2. 做菜: 西紅柿 
  3. 女兒的媽媽id: 169246904 
  4. 做菜: 雞蛋 

由兩次的運(yùn)行結(jié)果可知,修改之前打印的兩個(gè)內(nèi)存地址是相同的,而修改之后打印的兩個(gè)內(nèi)存地址不相同,說(shuō)明修改之后創(chuàng)建Monther類(lèi)的兩個(gè)實(shí)例是不同的實(shí)例,因此,這兩個(gè)實(shí)例分別調(diào)用get_food()方法時(shí),字符串不會(huì)進(jìn)行拼接,調(diào)用food()方法時(shí)打印結(jié)果也不相同。

綜上所述,單例模式只有唯一實(shí)例,解決資源共享問(wèn)題,節(jié)約系統(tǒng)內(nèi)存,提高系統(tǒng)運(yùn)行效率。

文章“【Python基礎(chǔ)知識(shí)】單例模式”已幫助

>>本文地址:http://m.hqfphsz.com/zhuanye/2021/68021.html

THE END  

聲明:本站稿件版權(quán)均屬中公教育優(yōu)就業(yè)所有,未經(jīng)許可不得擅自轉(zhuǎn)載。

1 您的年齡

2 您的學(xué)歷

3 您更想做哪個(gè)方向的工作?

獲取測(cè)試結(jié)果
  • 大前端大前端
  • 大數(shù)據(jù)大數(shù)據(jù)
  • 互聯(lián)網(wǎng)營(yíng)銷(xiāo)互聯(lián)網(wǎng)營(yíng)銷(xiāo)
  • JavaJava
  • Linux云計(jì)算Linux
  • Python+人工智能Python
  • 嵌入式物聯(lián)網(wǎng)嵌入式
  • 全域電商運(yùn)營(yíng)全域電商運(yùn)營(yíng)
  • 軟件測(cè)試軟件測(cè)試
  • 室內(nèi)設(shè)計(jì)室內(nèi)設(shè)計(jì)
  • 平面設(shè)計(jì)平面設(shè)計(jì)
  • 電商設(shè)計(jì)電商設(shè)計(jì)
  • 網(wǎng)頁(yè)設(shè)計(jì)網(wǎng)頁(yè)設(shè)計(jì)
  • 全鏈路UI/UE設(shè)計(jì)UI設(shè)計(jì)
  • VR/AR游戲開(kāi)發(fā)VR/AR
  • 網(wǎng)絡(luò)安全網(wǎng)絡(luò)安全
  • 新媒體與短視頻運(yùn)營(yíng)新媒體
  • 直播帶貨直播帶貨
  • 智能機(jī)器人軟件開(kāi)發(fā)智能機(jī)器人
 

快速通道fast track

近期開(kāi)班時(shí)間TIME