進擊のpython
單例模式
打印過東西嗎?
我們一般都是怎么打印東西?
拿着一個打印機,然后把要打印的東西按順序傳到打印機
然后再打印是吧
這就是單例模式
卧槽?
那單例模式到底是什么?
其實,單例模式是一種常用的軟件設計模式
在它的核心結構中只包含一個被稱為單例類的特殊類
通過單例模式可以保證系統中一個類只有一個實例而且該實例易於外界訪問,
從而方便對實例個數的控制並節約系統資源
如果希望在系統中某個類的對象只能存在一個,單例模式是最好的解決方案
我就問你,我這么說你能看懂嗎?
不光是你啊,我也整不明白啊
實踐是檢驗真理的唯一標准
所以,還是要用代碼,才能讓你更直觀的感受
我們可以模擬一個打印機不?
當然!畢竟面向對象是上帝模式的編程方式
上帝可是什么都能創造的!
class Printor(object):
def __init__(self, name):
self.name = name
pass
def p(self):
print(f"我是打印{self.name}的打印機")
pass
w = "Word"
p = "PDF"
e = "Excel"
# 做一個打印機,否則你拿啥打印啊
p1 = Printor(w)
p1.p()
p2 = Printor(p)
p2.p()
p3 = Printor(e)
p3.p()
對吧,這么寫
但是你就會發現一個十分重要的問題
print(p1, p2, p3)
我他娘的整出來三個打印機!
我一個打印機就能干的活,你給我整理了三個
難搞哦
上帝的心態發生了一些變化
我可不可以只有一個打印機,然后讓他自己工作呢?
你都考慮到了,上帝能沒有考慮到?
-
--new-- 方法
還記得我們以前曾經說過
在你執行和調用類的時候,類里面的--init--方法先執行
對吧!
但是其實
在執行--init--之前,先要執行--new--這個方法
給你整個例子,要不然啊
你都不信
class Printor(object): def __init__(self, name): self.name = name print("我是init方法") def __new__(cls, *args, **kwargs): print("我是new方法") def p(self): print(f"我是打印{self.name}的打印機") pass p = Printor("w")
我是new方法
是不是沒有調用--init--方法?
那系統是怎么寫的呢?
她是這么寫的
def __new__(cls, *args, **kwargs): print("我是new方法") return object.__new__(cls)
我是new方法 我是init方法
這個就是記住!
然后這不就是調用了嗎
那我們的需求是不是就變成了
我只有第一次的時候,做一個打印機,后面每一次想要打印的時候
就用這個打印機,而不用再繼續整一個了
class Printor(object): l = "" def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): if cls.l == "": obj = object.__new__(cls) cls.l = obj return obj else: return cls.l def p(self): print(f"我是打印{self.name}的打印機") pass w = "Word" p = "PDF" e = "Excel" # 做一個打印機,否則你拿啥打印啊 p1 = Printor(w) p2 = Printor(p) p3 = Printor(e) print(p1, p2, p3)
簡單的介紹一下主要的代碼塊
def __new__(cls, *args, **kwargs): if cls.l == "": # 在外面聲明一個用來存儲實例化對象的內存地址 obj = object.__new__(cls) # 將這個類進行實例化操作,並把地址傳給了obj cls.l = obj # 將實例化的地址傳給l return obj # 返回這個地址給self else: return cls.l # 如果我發現你已經實例化過一個對象了,那我就用你實例化的
你也發現了,我整出來的這三個打印機,實際上內存地址相同
所以說本質上還是一個打印機的使用
這樣就完成了一個打印機干很多事的操作
那其實,這種操作只是在重復的使用--init--方法
那么,里面的name就被重復的覆蓋然后賦值
所以在最后你打印的name
一定是最后放進打印機里面的屬性值
print(p1.name, p2.name, p3.name)
你拿到的結果就應該是
Excel Excel Excel
對吧,沒問題吧!
這個還是挺重要的,尤其是在面試的時候
所以說還是要看看學習一下的