1、什麼是單例模式
2、爲何用單例模式
- 當實例化屢次獲得的對象中存放的屬性都同樣的狀況,應該將多個對象指向同一個內存,即同一個實例

3、單例模式(類內部定義靜態方法)
# settings.py
IP = '1.1.1.1'
PORT = 3306
class Mysql:
__instacne = None
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod
def from_conf(cls):
if cls.__instacne is None:
cls.__instacne = cls(IP, PORT)
return cls.__instacne
obj1 = Mysql.from_conf()
obj2 = Mysql.from_conf()
obj3 = Mysql.from_conf()
print(obj1 is obj2 is obj3)
True
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('10.10.10.11', 3307)
print(obj4.__dict__)
{'ip': '10.10.10.11', 'port': 3307}
4、單例模式(裝飾器)
# settings.py
IP = '1.1.1.1'
PORT = 3306
def singleton(cls):
cls.__instance = cls(IP, PORT)
def wrapper(*args, **kwargs):
if len(args) == 0 and len(kwargs) == 0:
return cls.__instance
return cls(*args, **kwargs)
return wrapper
@singleton # Mysql = singleton(Mysql) # Mysql = wrapper
class Mysql:
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj1 = Mysql() # wrapper()
obj2 = Mysql() # wrapper()
obj3 = Mysql() # wrapper()
print(obj1 is obj2 is obj3)
True
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('1.1.1.4', 3308)
print(obj4.__dict__)
{'ip': '1.1.1.4', 'port': 3308}
5、單例模式(元類)
# settings.py
IP = '1.1.1.1'
PORT = 3306
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dic): # self = Mysql
super(Mymeta, self).__init__(class_name, class_bases, class_dic)
# 完成Mysql對象的初始化
self.__instance = self.__new__(self) # 造出一個Mysql的對象
self.__init__(self.__instance, IP, PORT) # 從配置文件中加載配置完成Mysql對象的初始化
print(self.__instance)
print(self.__instance.__dict__)
def __call__(self, *args, **kwargs): # self = Mysql
if len(args) == 0 and len(kwargs) == 0:
return self.__instance
obj = self.__new__(self)
self.__init__(obj, *args, **kwargs)
return obj
class Mysql(object, metaclass=Mymeta): # Mysql = Mymeta(...)
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
<__main__.Mysql object at 0x10c7f1f98>
{'ip': '1.1.1.1', 'port': 3306}
print(obj1 is obj2 is obj3)
True
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('10.10.10.11', 3308)
print(obj4.__dict__)
{'ip': '10.10.10.11', 'port': 3308}
print(Mysql.__dict__)
{'__module__': '__main__', '__init__': <function Mysql.__init__ at 0x10c6b1d90>, '__dict__': <attribute '__dict__' of 'Mysql' objects>, '__weakref__': <attribute '__weakref__' of 'Mysql' objects>, '__doc__': None, '_Mymeta__instance': <__main__.Mysql object at 0x10c7f1f98>}
