Python实现单例
單例模式(Singleton Pattern)是一種常用的軟件設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統中,某個類只能出現一個實例時,單例對象就能派上用場。
我們在使用class創建類的時候, 只會創建一個類對象, 但是, 當我們實例化這個類對象的時候, 一個類對象, 可以實例化出很多不同的對象, 而我們每次實例化出來一個對象, 就會在內存中重新分配一塊空間, 而今天介紹的單例模式, 就是為了解決上述問題, 使得由一個類對象所實例化出來的全部對象都指向同一塊內存空間.
?
要想弄明白為什么每個對象被實例化出來之后, 都會重新被分配出一塊新的內存地址, 就要清楚一個python中的內置函數__new__(), 它跟__init__()一樣, 都是對象在被創建出來的時候, 就自動執行的一個函數, init()函數, 是為了給函數初始化屬性值的, 而__new__()這個函數, 就是為了給對象在被實例化的時候, 分配一塊內存地址, 因此, 我們可以重寫__new__()這個方法, 讓他在第一次實例化一個對象之后, 分配一塊地址, 在此后的所有實例化的其他對象時, 都不再分配新的地址, 而繼續使用第一個對象所被分配的地址, 因此, 我們可以在類對象里, 定義一個類屬性, 初始值設為None, 如果這個值是None就調用父類的__new__()方法, 為其分配地址, 并返回這個地址(__new__方法一定要返回一個地址)
?
比如,某個服務器程序的配置信息存放在一個文件中,客戶端通過一個 AppConfig 的類來讀取配置文件的信息。如果在程序運行期間,有很多地方都需要使用配置文件的內容,也就是說,很多地方都需要創建 AppConfig 對象的實例,這就導致系統中存在多個 AppConfig 的實例對象,而這樣會嚴重浪費內存資源,尤其是在配置文件內容很多的情況下。事實上,類似 AppConfig 這樣的類,我們希望在程序運行期間只存在一個實例對象。
?
每次實例化一個對象時,都會先調用 __new__() 創建一個對象,再調用 __init__() 函數初始化數據。因而,在 new 函數中判斷 ExecSql類 是否已經實例化過,如果不是,調用父類的 new 函數創建實例;否則返回之前創建的實例。
_instance 作為類屬性,保證了所有對象的 _instance 都是同一個,我們可以看到下面例子中多個實例化的內存地址是一樣的,是最新實例的值
單例實際是當多處調用進行多次實例化時,當類已實例化過,直接用實例化好的對象,當類未實例化過時,進行實例化對象,多處調用進行多次實例化實際只發生了一次實例化,共用1個實例化對象內存地址,所以實例對象是一樣的
class ExecSql(object):_instance=Nonedef __new__(cls,*args,**kwargs):print("實例化時優先調用new方法,創建實例對象,這個方法是實現單例")if cls._instance is None:cls._instance=super().__new__(cls)return cls._instancedef __init__(self,name,age):print("實例化時,初始化方法,初始化一些數據")self.name=nameself.age=agetest1 = ExecSql("橙子",18) print(id(test1),id(test1.name),test1.name)test2 = ExecSql("柚子",33) print(id(test1),id(test1.name),test1.name) print(id(test2),id(test2.name), test2.name)"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/test/test02.py 實例化時優先調用new方法,創建實例對象,這個方法是實現單例 實例化時,初始化方法,初始化一些數據 2668768588352 2668766898976 橙子 實例化時優先調用new方法,創建實例對象,這個方法是實現單例 實例化時,初始化方法,初始化一些數據 2668768588352 2668768524368 柚子 2668768588352 2668768524368 柚子Process finished with exit code 0?
總結
以上是生活随笔為你收集整理的Python实现单例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java浮点数四舍五入_Java小程序练
- 下一篇: linux 电台,linux下架设个人电