1、什麼是單例模式
讓所有類在實例化時,指向同一個內存地址,稱之為單例模式 PS:無論產生多少個對象,都會指向 單個 實例
當在確定 "類中的屬性與方法不變" 需要反覆調用類時,會產生不同的對象,也會產生不同的內存地址,最終造成資源的浪費,如下例:
class Foo: def __init__(self, x, y): self.x = x self.y = yfoo_obj1 = Foo(10, 20)print(foo_obj1.__dict__)print(foo_obj1)foo_obj2 = Foo(10, 20)print(foo_obj2.__dict__)print(foo_obj2)
class Foo: def __init__(self, x, y): self.x = x self.y = yfoo_obj1 = Foo(10, 20)print(foo_obj1.__dict__)print(foo_obj1)foo_obj2 = Foo(10, 20)print(foo_obj2.__dict__)print(foo_obj2) 執行結果:
# foo_obj1和foo_obj2調用的屬性相同,但內存地址不同{'x': 10, 'y': 20}<__main__.Foo object at 0x0000000001E662C8> # foo_obj1的內存地址{'x': 10, 'y': 20}<__main__.Foo object at 0x0000000001E66408> # foo_obj2的內存地址 使用多個內存地址即浪費內存空間。
2、單例模式的優點
可以節省內存空間
3、單例模式實現方法
實現方法(*****):
1) 通過classmethod實現
2) 通過裝飾器實現
3) 通過__new__實現
4) 通過導入模塊時實現
5) 通過元類實現
例:假如資料庫被多臺伺服器調用啟動和關閉(使用classmethod實現)
class MySql: # 定義一個屬性默認值,用於判斷對象是否存在, 若對象不存在,屬性值默認是None # __instance是類的屬性 __instance = None def __init__(self, host, port): self.host = host self.port = port @classmethod def singleton(cls, host, port): # 單例方法 --> 類方法 # 判斷__instance中若沒有值,證明沒有對象 if not cls.__instance: # 產生一個對象並返回 obj = cls(host, port) # 從 None --> obj cls.__instance = obj # 若__instance有值,證明對象已經存在,則直接返回該對象 return cls.__instance def start_mysql(self): print("啟動資料庫。") def stop_mysql(self): print("關閉資料庫。")HOST1 = "192.168.9.1"PORT1 = "1532"HOST2 = "192.168.9.2"PORT2 = "1533"HOST3 = "192.168.9.3"PORT3 = "1534"obj1 = MySql.singleton(HOST1, PORT1)obj2 = MySql.singleton(HOST2, PORT2)obj3 = MySql.singleton(HOST3, PORT3)print(obj1)print(obj2)print(obj3) 執行結果:
# obj1、obj2、obj3調用的屬性相同,內存地址也相同<__main__.MySql object at 0x00000000021D6D48> # obj1的內存地址<__main__.MySql object at 0x00000000021D6D48> # obj2的內存地址<__main__.MySql object at 0x00000000021D6D48> # obj3的內存地址 使用同一個內存地址即節省內存空間。