Python实现单例模式的5种方法
本文详细介绍Python中实现单例模式的五种常用方法,包括元类、继承、装饰器、模块导入及类方法。分析各方式的优缺点,如内存节省与命名空间保护,同时指出无法继承等局限性,帮助开发者根据场景选择合适方案。
基本介绍
单例模式确保一个类仅有一个实例,并提供一个全局访问点来获取该实例。
作为创建型模式之一,单例模式因其应用广泛且实现相对简单而备受青睐。
该模式的核心特征在于全局唯一性,同时允许对实例状态进行修改。
优缺点
优势方面:
- 有效避免资源的多重占用问题,例如在文件写入操作中防止冲突。
- 通过复用实例来节省内存资源。
- 有助于防止命名空间被意外污染。
局限性包括:
- 由于缺乏接口支持,单例类无法被继承,这与单一职责原则存在冲突。一个类应专注于内部逻辑,而不应受限于外部实例化方式。
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))
以上就是Python实现单例模式的五种方法介绍,更多相关Python 单例模式内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









