Python之單例模式

2022-09-08 10:03:07 字數 4682 閱讀 7274

單例模式是一種常用的軟體設計模式,屬於建立型模式。單例模式的核心結構就是系統中乙個類只有乙個例項,保證了在程式的不同位置都可以且僅可以取到同乙個物件例項。

應用場景:

1.單例模式廣泛應用於各種開發場景:

遊戲中需要有「場景管理器」這樣一種東西,用來管理遊戲場景的切換、資源載入、網路連線等等任務。這個管理器需要有多種方法和屬性,在**中很多地方會被呼叫,且被呼叫的必須是同乙個管理器,否則既容易產生衝突,也會浪費資源

2.一些資源管理器常常設計成單例模式:

在計算機系統中,需要管理的資源包括軟體外部資源,譬如每台計算機可以有若干個印表機,但只能有乙個printer spooler,以避免兩個印表機作業同時輸出到印表機中。每台計算機可以有若干傳真機卡,但是只應該有乙個軟體負責管理傳真卡,以避免乙個通訊埠同時被兩個請求同時呼叫。

需要管理的資源包括軟體內部資源,譬如,大多數的軟體都有乙個(甚至多個)屬性(properties)檔案存放系統配置。這樣的系統應當由乙個物件來管理乙個屬性檔案。

1、常用的單例模式

class

singleton(object):

_instance =none

def__new__(cls, *args, **kwargs):

ifnot cls._instance

: cls.

_instance = super(singleton, cls).__new__(cls)

return cls._instance

s1 =singleton()

s2 =singleton()

print(s1 is s2) #

true

屬性共用的單例

"""

上面的第一種寫法,雖然建立的是同乙個例項,

但是屬性是不共用的,因為每次__init__都會重新設定

"""class

singleton(object):

_instance =none

def__new__(cls, *args, **kwargs):

ifnot

cls._instance:

cls._instance = super(singleton, cls).__new__

(cls)

return

cls._instance

def__init__

(self, name, age):

self.name =name

self.age =age

s1 = singleton(name="

小明", age=18)

print(s1.name, s1.age) #

小明 18

s2 = singleton(name="

小紅", age=17) #

這裡相當於是重新賦值了name和age,之後的name age都是這個值

print(s2.name, s2.age) #

小紅 17

print(s1 is s2) #

true

"""因此想要屬性也共用,__init__也需要處理

"""class

singleton(object):

_instance =none

_initialized =false

def__new__(cls, *args, **kwargs):

ifnot

cls._instance:

cls._instance = super(singleton, cls).__new__

(cls)

return

cls._instance

def__init__

(self, name, age):

ifnot

singleton._initialized:

self.name =name

self.age =age

singleton._initialized =true

s1 = singleton(name="

小明", age=18)

print(s1.name, s1.age) #

小明 18

s2 = singleton(name="

小紅", age=17)

print(s2.name, s2.age) #

小明 18

print(s1 is s2) #

true

加鎖的單例

import

time

import

threading

class

singleton(object):

lock = threading.rlock() #

定義一把鎖

_instance =none

def__new__(cls, *args, **kwargs):

ifcls._instance:

return cls._instance #

如果之前例項化過,沒必要再次例項化,因為都是同乙個例項

with cls.lock:

#避免當執行緒沒有返回例項前,另乙個執行緒也進來了,導致出現不止乙個例項

ifnot

cls._instance:

cls._instance = super(singleton, cls).__new__

(cls)

return

cls._instance

deftask(arg):

obj =singleton()

print

(obj)

for i in range(10):

t = threading.thread(target=task,args=(i,))

t.start()

time.sleep(10)

obj = singleton()

2、函式單例裝飾器

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

def__init__

(self, name):

self.name =name

a1 = a("

ming")

print(a1.name) #

ming

a2 = a("

dong")

print(a2.name) #

ming

3、類單例裝飾器

class

singleton(object):

def__init__

(self, cls):

self._cls =cls

self._instance ={}

def__call__(self, *args, **kwargs):

if self._cls not

inself._instance:

self._instance[self._cls] = self._cls(*args, **kwargs)

return

self._instance[self._cls]

@singleton

class

a():

def__init__

(self, name):

self.name =name

a1 = a("

ming")

print(a1.name) #

ming

a2 = a("

dong")

print(a2.name) #

ming

4、使用 metaclass 實現單例模式

class

singleton(type):

_instance ={}

def__call__(cls, *args, **kwargs):

if cls not

incls._instance:

cls._instance[cls] = super(singleton, cls).__call__(*args, **kwargs)

return

cls._instance[cls]

class a(metaclass=singleton):

def__init__

(self, name):

self.name =name

a1 = a("

ming")

print(a1.name) #

ming

a2 = a("

dong")

print(a2.name) #

ming

python之單例模式

單例模式 1.new 方法的使用 new 是乙個由object基類提供的內建的靜態方法,主要作用有兩個 在使用類名 建立物件時,python直譯器首先會呼叫 new 方法,為物件分配記憶體空間 python的直譯器獲得物件的引用後,將引用作為第乙個引數,傳遞給 init 方法 重寫 new 方法的 ...

Python設計模式之單例模式

站 物件 印表機 物件 使用類名 建立物件時,python 的直譯器首先 會 呼叫 new 方法為物件 分配空間。new 是乙個 由object基類提供的內建的靜態方法,主要作用有兩個 python 的直譯器獲得物件的 引用 後,將引用作為 第乙個引數,傳遞給 init 方法。重寫 new 方法 的...

python設計模式之單例模式

單例模式是一種建立型設計模式,它確保乙個類有且只有乙個特定型別的物件,並提供全域性訪問點。其意圖為 簡單理解 單例即為單個例項,也就是每次例項化建立物件時獲得的都是同乙個物件,當然同乙個物件的屬性都是相同的,方法也是相同的,位址也是相同的,這樣給我們帶來的好處就是可以避免消耗過多的記憶體或cpu資源...