基本介紹
一個物件只允許被一次建立,一個類只能建立一個物件,並且提供一個全域性訪問點。
單例模式應該是應用最廣泛,實現最簡單的一種建立型模式。
特點:全域性唯一,允許更改
優缺點
優點:
避免對資源的多重佔用,如寫入檔案操作
節省記憶體
防止名稱空間被汙染
缺點:
沒有介面,不能繼承,與單一職責原則衝突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來例項化
Python實現
方式1,元類實現:
class MetaClass(type):
def __call__(self, *args, **kwargs):
"""
self : class Singleton
"""
if not hasattr(self, "ins"):
insObject = super(__class__, self).__call__(*args, **kwargs)
setattr(self, "ins", insObject)
return getattr(self, "ins")
class Singleton(object, metaclass=MetaClass):
pass
if __name__ == "__main__":
ins = Singleton()
print(id(ins))
ins = Singleton()
print(id(ins))
方式2,繼承實現:
class ParentClass:
def __new__(cls, *args, **kwargs) -> object:
"""
cls : class Singeton
"""
if not hasattr(cls, "ins"):
insObject = super(__class__, cls).__new__(cls, *args, **kwargs)
setattr(cls, "ins", insObject)
return getattr(cls, "ins")
class Singleton(ParentClass):
pass
if __name__ == "__main__":
ins = Singleton()
print(id(ins))
ins = Singleton()
print(id(ins))
方式3,裝飾器實現:
def warpper(clsObject):
def inner(*args, **kwargs):
if not hasattr(clsObject, "ins"):
insObject = clsObject(*args, **kwargs)
setattr(clsObject, "ins", insObject)
return getattr(clsObject, "ins")
return inner
@warpper
class Singleton:
pass
if __name__ == "__main__":
ins = Singleton()
print(id(ins))
ins = Singleton()
print(id(ins))
方式4,模組實現:
- foo.py --> ins = Singleton()
- bar.py --> from foo import ins
方式5,@classmethod實現單例模式:
class Singleton:
@classmethod
def getSingletonInstanceObject(cls, *args, **kwargs):
if not hasattr(cls, "ins"):
insObject = cls(*args, **kwargs)
setattr(cls, "ins", insObject)
return getattr(cls, "ins")
if __name__ == "__main__":
ins = Singleton.getSingletonInstanceObject()
print(id(ins))
ins = Singleton.getSingletonInstanceObject()
print(id(ins))