亚洲 国产精品 日韩-亚洲 激情-亚洲 欧美 91-亚洲 欧美 成人日韩-青青青草视频在线观看-青青青草影院

千鋒教育-做有情懷、有良心、有品質的職業教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > Python實現單例模式的五種寫法,你都會嗎?

Python實現單例模式的五種寫法,你都會嗎?

來源:千鋒教育
發布人:qyf
時間: 2023-02-22 17:04:00 1677056640

  單例模式(Singleton Pattern) 是一種常用的軟件設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統中,某個類只能出現一個實例時,單例對象就能派上用場。

  比如,某個服務器程序的配置信息存放在一個文件中,客戶端通過一個 AppConfig 的類來讀取配置文件的信息。如果在程序運行期間,有很多地方都需要使用配置文件的內容,也就是說,很多地方都需要創建 AppConfig 對象的實例,這就導致系統中存在多個 AppConfig 的實例對象,而這樣會嚴重浪費內存資源,尤其是在配置文件內容很多的情況下。

  事實上,類似 AppConfig 這樣的類,我們希望在程序運行期間只存在一個實例對象。

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

  ●使用模塊

  ●使用裝飾器

  ●使用類

  ●基于 new 方法實現

  ●基于 metaclass 方式實現

  下面來詳細介紹:

  使用模塊

  其實,Python 的模塊就是天然的單例模式,因為模塊在第一次導入時,會生成 .pyc 文件,當第二次導入時,就會直接加載 .pyc 文件,而不會再次執行模塊代碼。

  因此,我們只需把相關的函數和數據定義在一個模塊中,就可以獲得一個單例對象了。

  如果我們真的想要一個單例類,可以考慮這樣做:

  class Singleton(object):

  def foo(self):

  pass

  singleton = Singleton()

  將上面的代碼保存在文件 mysingleton.py 中,要使用時,直接在其他文件中導入此文件中的對象,這個對象即是單例模式的對象

  from mysingleton import singleton

  使用裝飾器

  def Singleton(cls):

  _instance = {}

  def _singleton(*args, **kargs):

  if cls not in _instance:

  _instance[cls] = cls(*args, **kargs)

  return _instance[cls]

  return _singleton

  @Singleton

  class A(object):

  a = 1

  def __init__(self, x=0):

  self.x = x

  a1 = A(2)

  a2 = A(3)

  使用類

  class Singleton(object):

  def __init__(self):

  pass

  @classmethod

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

  if not hasattr(Singleton, "_instance"):

  Singleton._instance = Singleton(*args, **kwargs)

  return Singleton._instance

  一般情況,大家以為這樣就完成了單例模式,但是當使用多線程時會存在問題:

  class Singleton(object):

  def __init__(self):

  pass

  @classmethod

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

  if not hasattr(Singleton, "_instance"):

  Singleton._instance = Singleton(*args, **kwargs)

  return Singleton._instance

  import threading

  def task(arg):

  obj = Singleton.instance()

  print(obj)

  for i in range(10):

  t = threading.Thread(target=task,args=[i,])

  t.start()

  程序執行后,打印結果如下:

  <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    <main.Singleton object at 0x02C933D0>
    。

 

  看起來也沒有問題,那是因為執行速度過快,如果在 init 方法中有一些 IO 操作,就會發現問題了

  下面我們通過 time.sleep 模擬,我們在上面 init 方法中加入以下代碼:

  def init(self):

  import time

  time.sleep(1)

  重新執行程序后,結果如下:

  <main.Singleton object at 0x034A3410>
  <main.Singleton object at 0x034BB990>
  <main.Singleton object at 0x034BB910>
  <main.Singleton object at 0x034ADED0>
  <main.Singleton object at 0x034E6BD0>
  <main.Singleton object at 0x034E6C10>
  <main.Singleton object at 0x034E6B90>
  <main.Singleton object at 0x034BBA30>
  <main.Singleton object at 0x034F6B90>
  <main.Singleton object at 0x034E6A90>

  問題出現了!按照以上方式創建的單例,無法支持多線程。

  解決辦法:加鎖!未加鎖部分并發執行,加鎖部分串行執行,速度降低,但是保證了數據安全。

  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(arg):

  obj = Singleton.instance()

  print(obj)

  for i in range(10):

  t = threading.Thread(target=task,args=[i,])

  t.start()

  time.sleep(20)

  obj = Singleton.instance()

  print(obj)

  打印結果如下:

<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>
<main.Singleton object at 0x02D6B110>

  這樣就差不多了,但是還是有一點小問題,就是當程序執行時,執行了 time.sleep(20) 后,下面實例化對象時,此時已經是單例模式了。

  但我們還是加了鎖,這樣不太好,再進行一些優化,把 intance 方法,改成下面這樣就行:

  @classmethod

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

  if not hasattr(Singleton, "_instance"):

  with Singleton._instance_lock:

  if not hasattr(Singleton, "_instance"):

  Singleton._instance = Singleton(*args, **kwargs)

  return Singleton._instance

  這種方式實現的單例模式,使用時會有限制,以后實例化必須通過 obj = Singleton.instance()

  import time

  import threading

  class Singleton(object):

  _instance_lock = threading.Lock()

  def __init__(self):

  time.sleep(1)

  @classmethod

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

  if not hasattr(Singleton, "_instance"):

  with Singleton._instance_lock:

  if not hasattr(Singleton, "_instance"):

  Singleton._instance = Singleton(*args, **kwargs)

  return Singleton._instance

  def task(arg):

  obj = Singleton.instance()

  print(obj)

  for i in range(10):

  t = threading.Thread(target=task,args=[i,])

  t.start()

  time.sleep(20)

  obj = Singleton.instance()

  print(obj)

  如果用 obj = Singleton(),這種方式得到的不是單例。

  基于 new 方法實現

  通過上面例子,我們可以知道,當我們實現單例時,為了保證線程安全需要在內部加入鎖。

  我們知道,當我們實例化一個對象時,是先執行了類的 new 方法(我們沒寫時,默認調用 object.new),實例化對象;然后再執行類的 init 方法,對這個對象進行初始化,所有我們可以基于這個,實現單例模式。

  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(arg):

  obj = Singleton()

  print(obj)

  for i in range(10):

  t = threading.Thread(target=task,args=[i,])

  t.start()

  打印結果如下:

<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>
<main.Singleton object at 0x038B33D0>

  采用這種方式的單例模式,以后實例化對象時,和平時實例化對象的方法一樣 obj = Singleton() 。

  基于 metaclass 方式實現

  相關知識:

  類由 type 創建,創建類時,type 的 init 方法自動執行,類() 執行 type 的 call 方法(類的 new 方法,類的 init 方法) 對象由類創建,創建對象時,類的 init 方法自動執行,對象()執行類的 call 方法 例子:

  class Foo:

  def __init__(self):

  pass

  def __call__(self, *args, **kwargs):

  pass

  obj = Foo()

  # 執行type的 __call__ 方法,調用 Foo類(是type的對象)的 __new__方法,用于創建對象,然后調用 Foo類(是type的對象)的 __init__方法,用于對對象初始化。

  obj() # 執行Foo的 __call__ 方法

  元類的使用:

  class SingletonType(type):

  def __init__(self,*args,**kwargs):

  super(SingletonType,self).__init__(*args,**kwargs)

  def __call__(cls, *args, **kwargs): # 這里的cls,即Foo類

  print('cls',cls)

  obj = cls.__new__(cls,*args, **kwargs)

  cls.__init__(obj,*args, **kwargs) # Foo.__init__(obj)

  return obj

  class Foo(metaclass=SingletonType): # 指定創建Foo的type為SingletonType

  def __init__(self,name):

  self.name = name

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

  return object.__new__(cls)

  obj = Foo('xx')

  實現單例模式:

  import threading

  class SingletonType(type):

  _instance_lock = threading.Lock()

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

  if not hasattr(cls, "_instance"):

  with SingletonType._instance_lock:

  if not hasattr(cls, "_instance"):

  cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)

  return cls._instance

  class Foo(metaclass=SingletonType):

  def __init__(self,name):

  self.name = name

  obj1 = Foo('name')

  obj2 = Foo('name')

  print(obj1,obj2

  以上就是Python實現單例模式的五種寫法,快上手試試吧。希望本篇文章可以給大家帶來收獲,如果喜歡的話,歡迎收藏哦!后面會繼續分享更多Python技術知識的!

tags:
聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
天天躁日日躁狠狠躁一区| 双腿吊起揉捏花蒂| 四虎永久在线精品国产馆V视影院| 午夜精品一区二区三区在线观看 | 国产激情久久久久久熟女老人| 果冻传媒AⅤ毛片无码| 免费看30分钟打扑克教程| 色噜噜久久综合伊人一本| 亚洲AV无码国产精品麻豆天美| 中文无码熟妇人妻AV在线| 成在线人AV免费无码高潮喷水| 国精品无码人妻一区二区三区| 麻花豆传媒剧国产入口| 少妇人妻偷人精品无码视频新浪| 亚洲精品1卡2卡三卡23卡| JAPANESE日本护士XXX| 国产乱XXXXX97国语对白| 老司机久久99久久精品播放| 色偷偷色噜噜狠狠网站30根 | 扒开女人P添大荫蒂| 国产特级毛片AAAAAAA高清| 免费精品一区二区三区第35| 玩小雪跪趴把腿分到最大影视| 亚洲中文无码永久免| 成熟闷骚女邻居引诱2| 精品免费久久久久久久| 人妻中文无码就熟专区| 亚洲AV午夜成人片精品网站| JAPANESE少妇高潮潮喷| 国产亚洲情侣一区二区无| 女BBBB槡BBBB槡BBBB| 羞羞麻豆国产精品1区2区3区| 2020国产亚洲美女精品久久久| 国产精品福利一区二区久久| 麻花传媒剧国产MV在线看| 同性男男黄G片免费网站| 又湿又紧又大又爽A视频| 国产成人精品日本亚洲专区不卡| 老色鬼久久亚洲AV综合| 无码人妻久久久一区二区三区| 2021国产精品国产精华| 国产亚洲欧美日韩俺去了| 全球AV集中精品导航福利| 亚洲乱码日产精品BD在观看| 成视频年人黄网站免费视频| 久久狼人大香伊蕉国产| 铜铜铜铜铜铜铜铜好大好深色| 中文字幕一区日韩精品| 国内精品久久久久精免费| 日本XXXX裸体撤尿| 永久免费看啪啪的网站| 国产精品日韩欧美一区二区三区 | 久久久久久久久久久综合日本| 天天爽夜夜爽人人爽QC| 18禁免费无码无遮挡不卡网站| 黑森林精选AV导航| 日韩一区二区三区精品视频| 中国A级毛片免费| 狠狠躁夜夜躁人人爽天天不| 色老头精品午夜福利视频| 中文字幕无码家庭乱欲| 护士HD老师FREE性ⅩⅩⅩⅩ| 十八禁羞羞爽爽爽爱爱午夜网| 67194人成免费无码| 精品国际久久久久999波多野| 特级做A爰片毛片免费看无码| 99久久人妻精品免费一区| 久99久无码精品视频免费播放| 无码熟熟妇丰满人妻PORN| 波多野结衣456| 男男19禁啪啪无遮挡免费| 亚洲人成网站在线播放2020| 国产毛片精选好视频| 三个医生换着躁我一个| 9色国产深夜内射| 久久夜色撩人精品国产| 亚洲国产成人片在线观看无码| 国产成人无码久久久精品一| 日本高清视频色WWWWWW色| 67194熟妇在线直接进入百度| 久久久精品人妻一区二区三区| 亚洲AV毛茸茸av成熟女人| 关晓彤露内毛黑森林| 人妻熟女AⅤ中文字幕在线看| 综合无码一区二区三区四区五区 | 亚洲视频日韩视欧美视频| 国产午夜精品无码| 天无日天天射天天视| 成人欧美一区二区三区1314| 欧美性饥渴少妇XXXⅩOOOO| 中文无码人妻影音先锋| 久久久久人妻精品一区三寸| 亚洲精品456在线播放| 国产亚洲人成在线视频网站| 无码AV免费不卡在线观看| 丰满人妻熟妇乱偷人无码出轨| 人妻AV中文字幕一区二区三区| 97久久精品人人澡人人爽| 综合无码成人AⅤ视频在线观看| 在线观看亚洲AV每日更新| 国产综合久久久久久鬼色| 无码日韩人妻AV一区免费| 国产96在线 | 亚洲| 日产精品卡二卡三卡四妈妈的朋友| 99久久免费精品国产72精品九 | 国产成年无码久久久久毛片| 日韩精品无码人成视频| 被多人玩弄的烂货苏妖精| 欧美日韩人妻精品一区二区三区| 制服丝袜另类专区制服| 乱人伦中文视频在线| 在线观看无码H片| 免费无码又爽又刺激高潮软件| 中文字幕精品亚洲一区| 免费A级毛片无码A∨蜜芽试看| 又色又爽又黄的裸体美女图片| 久久亚洲AV无码西西人体| 英语老师没戴套让我C了一节课| 久久国产精品日本波多野结衣| 亚洲人成色777777精品百度| 久久国产乱子精品免费女| 亚洲综合无码一区二区痴汉| 久久精品国产99精品国产2| 亚洲综合国产成人无码| 久久综合国产乱子伦精品免费 | 丰满人妻AV无码一区二区三区| 日日摸日日碰夜夜爽暖暖视频| 多P混交群体交乱的安全保障| 涩爱AV挺进少妇张开双暴躁| 干的你走不了路SB| 无码人妻久久一区二区三区APP | 国产成人无码A区在线观看视频免| 撕开奶罩揉吮奶头免费视频| 国产成人一区二区| 亚洲Ⅴ国产V天堂A无码二区| 韩国AV一区二区| 亚洲一卡一卡二新区无人区| 老牛天天晚上夜噜噜噜| 939W78W78W乳液特色| 人妻办公室内上司侵犯| 从今天开始当城主| 同性男男黄G片免费网站| 国内精品久久久久久影院| 亚洲乱码中文字幕综合234| 久久综合激激的五月天| AV无码AV不卡一区二区| 日韩精品无码一区二区三区视频 | 国产23在线 | 传媒麻豆| 西西444WWW无码大胆| 久久成人国产精品免费软件| 自拍偷自拍亚洲精品播放| 人妻AV无码系列一区二区三区| 公玩弄年轻人妻HD| 亚洲AV综合色区无码二区爱AV| 久久五月丁香综合中文亚洲| FREEXXXX国产HD中文对白| 首页 动漫 亚洲 欧美 日韩| 床震吃胸膜奶免费视频| 麻花豆传媒剧国产MV网站入口| 99热门精品一区二区三区无码| 人妻丰满熟妇av无码区HD优| 国产经典一区二区三区蜜芽| 亚洲国产精品久久久久4婷婷 | 日出水了好深好涨| 国产美女遭强高潮开双腿| 野花免费观看日本电视剧| 朋友人妻少妇精品系列| 国产精品99久久久久久宅男小说| 亚洲老熟女 @ TUBEUM| 欧美ZC0O人与善交的最新章节| 隔壁老王国产在线精品| 亚洲精品高清国产一久久| 欧美成人精品三级网站下载| 公车上双乳被老汉揉搓玩弄漫画| 亚洲国产成人片在线观看无码| 免费看老外操B视频| 高清人人天天夜夜曰狠狠狠狠| 亚洲精品无码不卡在线播HE| 欧美XXXXX高潮喷水| 国产成人亚洲精品| 亚洲一区二区三区自拍公司 | 亚洲成AV人片不卡无码| 女人张开腿让男人添| 国产精品99无码一区二区| 一炕四女被窝交换啪啪| 三级无码在钱AV无码在钱| 精品亚洲A∨无码一区二区三区| YW尤物无码点击进入| 亚洲AV无码久久精品蜜桃| 欧美XXXxX高潮喷水| 国产人与ZOXXXX另类| 1313午夜精品理论片| 无码一区二区三区| 男女24式动态图| 国产精品一区二区 尿失禁| 中文字幕无码视频手机免费看| 无码久久一区二区| 猫咪WWW免费人成网站| 国产精品亚洲欧美大片在线观看| 中文中文字幕成人无码AⅤ|