91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在python中實現單例

發布時間:2021-01-06 16:28:03 來源:億速云 閱讀:152 作者:Leah 欄目:開發技術

如何在python中實現單例?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

什么是單例?

確保某一個類只有一個實例,而且自行實例化并向整個系統提供這個實例,這個類稱為單例類,單例模式是一種對象創建型模式。

那么單例模式有什么用途呢?舉個常見的單例模式例子,我們平時使用的電腦上都有一個回收站,在整個操作系統中,回收站只能有一個實例,整個系統都使用這個唯一的實例,而且回收站自行提供自己的實例,因此回收站是單例模式的應用。

裝飾器的方式

這種方式也是工作中經常用的一種,用起來也比較方便,代碼實現如下

def Singleton(cls):
 _instance = {}

 def _singleton(*args, **kwargs):
  if cls not in _instance:
   _instance[cls] = cls(*args, **kwargs)
  return _instance[cls]

 return _singleton

如果我們工作的一個類需要用單例就通過類似下面的方式實現即可:

@Singleton
class A(object):

 def __init__(self, x):
  self.x = x

我個人還是挺喜歡這種方式的

類的方式實現

這里其實有一些問題就需要注意了,先看一下可能出現的錯誤代碼

class Member(object):

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

乍一看這個類好像已經實現了單例,但是這里有一個潛在的問題,就是如果是多線程的情況,這樣寫就會有問題了,尤其是在當前類的初始化對象里有一些耗時操作時候

例如下面代碼:

#! /usr/bin/env python3
# .-*- coding:utf-8 .-*-

import time
import threading
import random


class Member(object):
 
 def __init__(self):
  time.sleep(random.randint(1,3))

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


def task(arg):
 obj = Member.instance()
 print(obj)

for i in range(5):
 t = threading.Thread(target=task, args=[i,])
 t.start()

這段代碼的執行結果會出現實例化了多個對象,導致你寫的單例就沒起到作用

當然自然而然我們會想起加鎖,通過鎖來控制,所以我們將上面代碼進行更改:

#! /usr/bin/env python3
# .-*- coding:utf-8 .-*-


import time
import threading
import random


class Member(object):
 _instance_lock = threading.Lock()

 def __init__(self):
  i = random.randint(1, 3)
  print(i)
  time.sleep(i)

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


def task():
 obj = Member.instance()
 print(obj)

for i in range(5):
 threading.Thread(target=task,).start()

但是上面的代碼還有一個問題,就是當我們已經實例化過之后每次調用instance都會去請求鎖,所以這點并不好,所以我們將這部分代碼再次更改:

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

看完上述內容,你們掌握如何在python中實現單例的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

冀州市| 如东县| 阿鲁科尔沁旗| 突泉县| 华容县| 城市| 方山县| 辛集市| 东乡| 蓝山县| 杭锦后旗| 苏尼特左旗| 沧州市| 雅江县| 仪征市| 澎湖县| 凤台县| 新化县| 二连浩特市| 綦江县| 建水县| 哈密市| 绥化市| 阜宁县| 原阳县| 会理县| 剑河县| 天柱县| 沾益县| 普定县| 开江县| 福清市| 鄂托克旗| 民丰县| 平顶山市| 陈巴尔虎旗| 花莲县| 琼海市| 朝阳区| 茶陵县| 洛扎县|