Python設計模式——單例模式
一、單例模式理論
單例模式: 保證某一個類只有一個例項,而且在全域性只有一個訪問點 優點: 1、由於單例模式要求在全域性內只有一個例項,因而可以節省比較多的記憶體空間 2、全域性只有一個接入點,可以更好地進行資料同步控制,避免多重佔用 3、單例可長駐記憶體,減少系統開銷 缺點: 1、單例模式的擴充套件是比較困難的 2、賦予了單例模式太多的職責,某種程度上違反了單一職責原則(六大設計原則之一) 3、單例模式是併發協作軟體模組中需要最先完成的,因而其不利於測試 4、單例模式在某種情況下會導致資源瓶頸 應用場景: 1、生成全域性唯一的變數,比如序列號 2、訪問全域性複用的唯一資源,如磁碟,匯流排等 3、單個物件佔用的資源太多,如資料庫等 4、系統全域性統一管理,如windows下的工作管理員
二、對__new__的分析
# class Demo:
# def __init__(self, name):
# self.name = name
#
# def show_name(self):
# print("Name is: {}".format(self.name))
#
# if __name__ == '__main__':
#
# d = Demo("toby")
# d.show_name()
'''
引用大神的描述:
這樣便是__init__最普通的用法了。但__init__其實不是例項化一個類的時候第一個被呼叫的方法。
當使用Demo("toby")這樣的表示式來例項化一個類時,最先被呼叫的方法其實是 __new__ 方法。
__new__ 方法是什麼?
__new__方法接受的引數雖然也是和__init__一樣,但__init__是在類例項建立之後呼叫,而__new__方法正是建立這個類例項的方法。
'''
class Demo:
def __new__(cls, name):
print("Call __new__")
class_instance = super(Demo, cls).__new__(cls)
print("new建立了類例項:", class_instance) #列印一下
return class_instance #返回Demon類的一個例項給__init__,然後利用這個例項來呼叫類的__init__方法
def __init__(self, name): #那__init__用什麼來接收__new__返回來的類例項呢?答案就是self
print("init接收到new返回回來的類例項:", self) #列印一下這個self,也就是看一下由__new__產生的例項
print("Call __init__")
self.name = name
def show_name(self):
print("Name is: {}".format(self.name))
#
# if __name__ == '__main__':
# d = Demo("toby")
# d.show_name()
'''
引用大神的總結:
所以,__init__ 和 __new__ 最主要的區別在於:
1、__init__ 通常用於初始化一個新例項,控制這個初始化的過程,比如新增一些屬性,
做一些額外的操作,發生在類例項被建立完以後。它是例項級別的方法。
2、__new__ 通常用於控制生成一個新例項的過程。它是類級別的方法。
但是說了這麼多,__new__最通常的用法是什麼呢,我們什麼時候需要__new__?,單例模式就是一個很好的例子
'''
三、單例模式(案例1)
#coding:utf-8
import threading
import time
#這裡使用方法__new__來實現單例模式
class Singleton(object): #抽象單例
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kwargs)
return cls._instance
#匯流排
class Bus(Singleton):
lock = threading.RLock()
def sendData(self, data):
self.lock.acquire()
time.sleep(3)
print("Sending Signal Data...", data)
self.lock.release()
#執行緒物件,為更加說明單例的含義,這裡講Bus物件例項化在了run裡
class VisitEntity(threading.Thread):
my_bus = ""
name = ""
def getName(self):
return self.name
def setName(self, name):
self.name = name
def run(self):
self.my_bus = Bus()
self.my_bus.sendData(self.name)
if __name__ == '__main__':
for i in range(3):
print("Entity {} begin to run...".format(i))
v = VisitEntity()
v.setName("Toby"+str(i))
v.start()
四、單例模式(案例2)
#使用__new__類方法來保證只有一個例項被建立出來
class OneOnly(object):
_singleton = None
def __new__(cls, *args, **kwargs):
if not cls._singleton: #判斷是否建立有例項,如果沒有則呼叫super()函式來建立它
cls._singleton = super(OneOnly, cls).__new__(cls) #構造方法__new__被呼叫時,會構造該類的一個新例項
return cls._singleton
#定義一個普通的類,僅有初始化方法__init__
class Test:
def __init__(self, name):
self.name = name
#定義一個Demo類,並繼承實現單例模式的OneOnly類
class Demo(OneOnly):
def __init__(self, name):
self.name = name
def chage_name(self, new_name):
self.name = new_name
def show_name(self):
print("Name is: {}".format(self.name))
if __name__ == '__main__':
#當透過OneOnly類中的構造方法構造例項時,總是會的得到完全相同的例項,記憶體地址也相同
# o1 = OneOnly()
# o2 = OneOnly()
# print(o1)
# print(o2)
#透過Test類建立出來的兩個例項t1和t2,是兩個不同的例項,記憶體地址也是不同的
# t1 = Test("toby")
# t2 = Test("ttr")
# print(t1)
# print(t2)
#Demo類繼承了實現了單例模式的OneOnly類,因此,透過Demo類例項化出來的物件都是同一個物件
d1 = Demo("toby")
d2 = Demo("ttr")
d3 = Demo("laowang")
# 透過列印可知,他們的記憶體地址都是一樣的
# print(d1)
# print(d2)
#發現列印出來的name都是"laowang",似乎最後建立的一個例項把前兩個的給覆蓋了
d1.show_name()
d2.show_name()
d3.show_name()
#透過例項d1修改名字後,再透過例項d3和d2來檢視,果然也一起改變了。由此證明他們確實是同一個例項
d1.chage_name("juck")
d3.show_name()
d2.show_name()
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2318/viewspace-2809934/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- # Python設計模式 單例模式Python設計模式單例
- python設計模式-單例模式Python設計模式單例
- 用Python實現設計模式——單例模式Python設計模式單例
- 設計模式(單例模式)設計模式單例
- [設計模式] 單例模式設計模式單例
- 設計模式-單例模式設計模式單例
- 設計模式 —— 單例模式設計模式單例
- 設計模式 單例模式設計模式單例
- 設計模式——單例模式設計模式單例
- 設計模式-單例模式、多例模式設計模式單例
- 設計模式之單例設計模式設計模式單例
- 設計模式(一)_單例模式設計模式單例
- 常用設計模式-單例模式設計模式單例
- 設計模式之單例模式設計模式單例
- Java設計模式【單例模式】Java設計模式單例
- Java設計模式 | 單例模式Java設計模式單例
- 001設計模式:單例模式設計模式單例
- 設計模式一(單例模式)設計模式單例
- 設計模式之☞單例模式設計模式單例
- Java設計模式——單例模式Java設計模式單例
- Java設計模式–單例模式Java設計模式單例
- js設計模式--單例模式JS設計模式單例
- Java設計模式-單例模式Java設計模式單例
- 設計模式(二)——單例模式設計模式單例
- 設計模式之---單例模式設計模式單例
- Java設計模式--單例模式Java設計模式單例
- 設計模式—singleton(單例模式)設計模式單例
- 設計模式總結 —— 單例設計模式設計模式單例
- JavaScript設計模式初探--單例設計模式JavaScript設計模式單例
- 單例設計模式單例設計模式
- Javascript設計模式之單例模式JavaScript設計模式單例
- PHP 設計模式之——單例模式PHP設計模式單例
- Javascript設計模式(三)單例模式JavaScript設計模式單例
- golang設計模式之單例模式Golang設計模式單例
- jS設計模式二:單例模式JS設計模式單例
- 前端設計模式(2)--單例模式前端設計模式單例
- JS設計模式(二)--- 單例模式JS設計模式單例
- js設計模式之單例模式JS設計模式單例