單例模式
在某些場景下,咱們但願實體類不管實例化多少次都只會產生一個實體對象,這時候就須要使用單例模式。常用的場景就是全局配置類。
模式框架
"""使用函數定義裝飾器"""
def singletons(cls):
"""
定義一個單例裝飾器,使用dict保存定義好的實體,key爲class的地址而不是名字,這樣同名類也不會衝突
"""
instances = {}
def wrapper(*args, **kwargs):
if cls not in instances.keys():
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
"""使用類定義裝飾器"""
class singletons(object):
instances = {}
def __init__(self, cls):
self.__cls = cls
def __call__(self, *args, **kwargs):
if self.__cls not in singletons.instances.keys():
singletons.instances[self.__cls] = self.__cls(*args, **kwargs)
return singletons.instances[self.__cls]
- 方式2:重寫
__new__
方法,只能針對當前修改的類有效
class SingletonTest(object):
__instance = None
__isFirstInit = False
def __new__(cls, name):
if not cls.__instance:
SingletonTest.__instance = super().__new__(cls)
return cls.__instance
def __init__(self, name):
if not self.__isFirstInit:
self.__name = name
SingletonTest.__isFirstInit = True
def getName(self):
return self.__name
UML圖

示例
@singletons
class Test(object):
def __init__(self, name):
self.__name = name
def hello(self):
print("I am {} object {}".format(self.__name, id(self)))
if __name__ == "__main__":
test1 = Test("test1")
test2 = Test("test2")
test1.hello()
test2.hello()
'''測試輸出'''
# I am test1 object 2453169112512
# I am test1 object 2453169112512
擴展思考
- 單例模式的線程安全問題。