最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

5種Python單例模式的實現(xiàn)方式

 更新時間:2016年01月14日 14:48:35   投稿:lijiao  
這篇文章主要為大家介紹了5種Python單例模式的實現(xiàn)方式,所謂單例,是指一個類的實例從始至終只能被創(chuàng)建一次,對單例感興趣的小伙伴們可以參考一下

本文為大家分享了Python創(chuàng)建單例模式的5種常用方法,供大家參考,具體內(nèi)容如下

所謂單例,是指一個類的實例從始至終只能被創(chuàng)建一次。
方法1:
如果想使得某個類從始至終最多只有一個實例,使用__new__方法會很簡單。Python中類是通過__new__來創(chuàng)建實例的:

class Singleton(object):
  def __new__(cls,*args,**kwargs):
    if not hasattr(cls,'_inst'):
      cls._inst=super(Singleton,cls).__new__(cls,*args,**kwargs)
    return cls._inst
if __name__=='__main__':
  class A(Singleton):
    def __init__(self,s):
      self.s=s   
  a=A('apple')  
  b=A('banana')
  print id(a),a.s
  print id(b),b.s

結(jié)果:
29922256 banana
29922256 banana
通過__new__方法,將類的實例在創(chuàng)建的時候綁定到類屬性_inst上。如果cls._inst為None,說明類還未實例化,實例化并將實例綁定到cls._inst,以后每次實例化的時候都返回第一次實例化創(chuàng)建的實例。注意從Singleton派生子類的時候,不要重載__new__。
方法2:
有時候我們并不關(guān)心生成的實例是否具有同一id,而只關(guān)心其狀態(tài)和行為方式。我們可以允許許多個實例被創(chuàng)建,但所有的實例都共享狀態(tài)和行為方式:

class Borg(object):
  _shared_state={}
  def __new__(cls,*args,**kwargs):
    obj=super(Borg,cls).__new__(cls,*args,**kwargs)
    obj.__dict__=cls._shared_state
    return obj

將所有實例的__dict__指向同一個字典,這樣實例就共享相同的方法和屬性。對任何實例的名字屬性的設置,無論是在__init__中修改還是直接修改,所有的實例都會受到影響。不過實例的id是不同的。要保證類實例能共享屬性,但不和子類共享,注意使用cls._shared_state,而不是Borg._shared_state。
因為實例是不同的id,所以每個實例都可以做字典的key:

if __name__=='__main__':
  class Example(Borg):
    pass
  a=Example()
  b=Example()
  c=Example()
  adict={}
  j=0
  for i in a,b,c:
    adict[i]=j
    j+=1
  for i in a,b,c:
    print adict[i]

結(jié)果:
0
1
2
如果這種行為不是你想要的,可以為Borg類添加__eq__和__hash__方法,使其更接近于單例模式的行為:

class Borg(object):
  _shared_state={}
  def __new__(cls,*args,**kwargs):
    obj=super(Borg,cls).__new__(cls,*args,**kwargs)
    obj.__dict__=cls._shared_state
    return obj
  def __hash__(self):
    return 1
  def __eq__(self,other):
    try:
      return self.__dict__ is other.__dict__
    except:
      return False
if __name__=='__main__':
  class Example(Borg):
    pass
  a=Example()
  b=Example()
  c=Example()
  adict={}
  j=0
  for i in a,b,c:
    adict[i]=j
    j+=1
  for i in a,b,c:
    print adict[i]

結(jié)果:
2
2
2
所有的實例都能當一個key使用了。
方法3
當你編寫一個類的時候,某種機制會使用類名字,基類元組,類字典來創(chuàng)建一個類對象。新型類中這種機制默認為type,而且這種機制是可編程的,稱為元類__metaclass__ 。

class Singleton(type):
  def __init__(self,name,bases,class_dict):
    super(Singleton,self).__init__(name,bases,class_dict)
    self._instance=None
  def __call__(self,*args,**kwargs):
    if self._instance is None:
      self._instance=super(Singleton,self).__call__(*args,**kwargs)
    return self._instance
if __name__=='__main__':
  class A(object):
    __metaclass__=Singleton    
  a=A()
  b=A()
  print id(a),id(b)

結(jié)果:
34248016 34248016
id是相同的。
例子中我們構(gòu)造了一個Singleton元類,并使用__call__方法使其能夠模擬函數(shù)的行為。構(gòu)造類A時,將其元類設為Singleton,那么創(chuàng)建類對象A時,行為發(fā)生如下:
A=Singleton(name,bases,class_dict),A其實為Singleton類的一個實例。
創(chuàng)建A的實例時,A()=Singleton(name,bases,class_dict)()=Singleton(name,bases,class_dict).__call__(),這樣就將A的所有實例都指向了A的屬性_instance上,這種方法與方法1其實是相同的。
 方法4
python中的模塊module在程序中只被加載一次,本身就是單例的??梢灾苯訉懸粋€模塊,將你需要的方法和屬性,寫在模塊中當做函數(shù)和模塊作用域的全局變量即可,根本不需要寫類。
而且還有一些綜合模塊和類的優(yōu)點的方法:

class _singleton(object):
  class ConstError(TypeError):
    pass
  def __setattr__(self,name,value):
    if name in self.__dict__:
      raise self.ConstError
    self.__dict__[name]=value
  def __delattr__(self,name):
    if name in self.__dict__:
      raise self.ConstError
    raise NameError
import sys
sys.modules[__name__]=_singleton()

python并不會對sys.modules進行檢查以確保他們是模塊對象,我們利用這一點將模塊綁定向一個類對象,而且以后都會綁定向同一個對象了。
將代碼存放在single.py中:

>>> import single
>>> single.a=1
>>> single.a=2

ConstError
>>> del single.a
ConstError
方法5:
最簡單的方法:

class singleton(object):
  pass
singleton=singleton()

將名字singleton綁定到實例上,singleton就是它自己類的唯一對象了。

以上就是Python單例模式的實現(xiàn)方式詳細介紹,希望對大家的學習有所幫助。

相關(guān)文章

  • python 連接各類主流數(shù)據(jù)庫的實例代碼

    python 連接各類主流數(shù)據(jù)庫的實例代碼

    下面小編就為大家分享一篇python 連接各類主流數(shù)據(jù)庫的實例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Python面向?qū)ο缶幊讨械念惡蛯ο髮W習教程

    Python面向?qū)ο缶幊讨械念惡蛯ο髮W習教程

    這篇文章主要介紹了Python面向?qū)ο缶幊讨械念惡蛯ο髮W習教程,面向?qū)ο笫荘ython的基礎特性,其中的類與對象的特性和使用方法是Python學習當中的基本功,需要的朋友可以參考下
    2015-03-03
  • Django框架中的對象列表視圖使用示例

    Django框架中的對象列表視圖使用示例

    這篇文章主要介紹了Django框架中的對象列表視圖使用示例,Django是重多Python人氣web框架中最為著名的一個,需要的朋友可以參考下
    2015-07-07
  • Python PyQt5實現(xiàn)拖拽與剪貼板功能詳解

    Python PyQt5實現(xiàn)拖拽與剪貼板功能詳解

    這篇文章主要為大家詳細介紹了Python PyQt5如何實現(xiàn)拖拽與剪貼板功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-12-12
  • Python爬蟲爬取ts碎片視頻+驗證碼登錄功能

    Python爬蟲爬取ts碎片視頻+驗證碼登錄功能

    這篇文章主要介紹了Python爬蟲爬取ts碎片視頻+驗證碼登錄功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • 利用python對Excel中的特定數(shù)據(jù)提取并寫入新表的方法

    利用python對Excel中的特定數(shù)據(jù)提取并寫入新表的方法

    今天小編就為大家分享一篇利用python對Excel中的特定數(shù)據(jù)提取并寫入新表的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • Python中DrissionPage的示例代碼

    Python中DrissionPage的示例代碼

    DrissionPage是一款集成了Selenium和Requests功能的Python庫,本文就來介紹一下DrissionPage的具體使用,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-12-12
  • Python下使用Scrapy爬取網(wǎng)頁內(nèi)容的實例

    Python下使用Scrapy爬取網(wǎng)頁內(nèi)容的實例

    今天小編就為大家分享一篇Python下使用Scrapy爬取網(wǎng)頁內(nèi)容的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • python3 kmp 字符串匹配的方法

    python3 kmp 字符串匹配的方法

    這篇文章主要介紹了python3 kmp 字符串匹配的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • 你眼中的Python大牛 應該都有這份書單

    你眼中的Python大牛 應該都有這份書單

    現(xiàn)在學習Python途徑很多,但是想系統(tǒng)的學習Python的知識體系,還需要靠閱讀專業(yè)的書籍來不斷積累。你眼中的Python大牛,應該都看過這些書,趕快收藏一份
    2017-10-10

最新評論

双柏县| 湟中县| 泸州市| 乐平市| 聂荣县| 马边| 金华市| 蓝山县| 苍梧县| 瑞昌市| 海安县| 绥棱县| 伊金霍洛旗| 安吉县| 溆浦县| 正定县| 浮山县| 仁布县| 郴州市| 集安市| 砚山县| 安丘市| 讷河市| 永仁县| 盐池县| 松滋市| 深州市| 南华县| 丰宁| 郴州市| 喀喇| 衡水市| 绥中县| 德保县| 三江| 东平县| 科技| 安宁市| 镇宁| 隆德县| 无极县|