關於python單例的常用幾種實現方法

2021-09-08 20:23:31 字數 2797 閱讀 8099

這兩天在看自己之前寫的**,所以正好把用過的東西整理一下,單例模式,在日常的**工作中也是經常被用到,

所以這裡把之前用過的不同方式實現的單例方式整理一下

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

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

ifnot 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):

ifnot hasattr(member, "

_instance"):

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

return

member._instance

deftask(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:

ifnot hasattr(member, "

_instance"):

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

return

member._instance

deftask():

obj =member.instance()

print

(obj)

for i in range(5):

threading.thread(target=task,).start()

但是上面的**還有乙個問題,就是當我們已經例項化過之後每次呼叫instance都會去請求鎖,所以這點並不好,所以我們將這部分**再次更改:

@classmethod

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

ifnot hasattr(member, "

_instance"):

with member._instance_lock:

ifnot hasattr(member, "

_instance"):

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

return member._instance

這樣就很好的實現乙個可以多執行緒使用的單例

幾種常用的單例模式

單例模式的定義 單例模式的特點 執行緒安全問題 實現單例模式的方法 餓漢式 public class single 提供公共靜態方法 public static single getsingle public class single1 提供公共靜態方法 public static single1 ...

關於幾種單例模式的介紹

關於單例模式,需要解決三個方面的問題 1 執行緒安全問題。2 效能問題。3 懶載入 資源占有問題 關於下面幾種方式的缺點,除了dcl,holder和列舉單例模式其他只做簡單描述,具體可自行了解。public class lazy public synchronized static lazy get...

介紹幾種python實現單例的方法

實現單例的方法可以有很多種,但他們的原理都是相通的,即當第二次再去建立物件的時候都會返回第一次所建立的物件 第一種 使用裝飾器 第一次建立myclass的例項物件時,字典instances為空,將會返回乙個物件,並且該物件的引用也將儲存到instances裡面,當再次建立物件的時候則會返回第一次建立...