2026/2/20 19:54:01
网站建设
项目流程
职业教育网站开发,网站建设要学习什么,杭州制作网站公司,产品销售推广方案Python 中的单例模式#xff08;Singleton Pattern#xff09;
单例模式是一种创建型设计模式#xff0c;其核心目的是#xff1a;确保一个类全局只有一个实例#xff0c;并提供一个全局访问点来获取该实例。
常见应用场景#xff1a;
数据库连接池日志器#xff08;…Python 中的单例模式Singleton Pattern单例模式是一种创建型设计模式其核心目的是确保一个类全局只有一个实例并提供一个全局访问点来获取该实例。常见应用场景数据库连接池日志器Logger配置管理器Config Manager线程池缓存对象单例模式的优点节省资源只创建一次全局统一访问控制实例数量缺点难以单元测试全局状态可能隐藏依赖关系在多线程环境下需小心实现Python 中实现单例模式的几种常见方式Python 是动态语言实现单例非常灵活。下面从简单到推荐依次介绍。1. 使用模块级变量最 Pythonic最推荐Python 模块本身就是天然的单例所有导入模块的代码共享同一个实例。# singleton.pyclass_Singleton:def__init__(self):print(Singleton created)defdo_something(self):print(Doing something...)instance_Singleton()# 模块级实例只创建一次# 在其他文件中使用# from singleton import instancefromsingletonimportinstanceprint(instance)# 同一个对象instance.do_something()优点简单、无需额外代码、线程安全、天生单例这是大多数 Python 项目中实际使用的“单例”方式。2. 使用__new__方法重写经典方式classSingleton:_instanceNonedef__new__(cls,*args,**kwargs):ifcls._instanceisNone:cls._instancesuper().__new__(cls)returncls._instancedef__init__(self):# 注意__init__ 可能会被调用多次# 如果需要初始化逻辑要防止重复执行ifnothasattr(self,_initialized):print(Initializing singleton...)self._initializedTrue# 测试s1Singleton()s2Singleton()print(s1iss2)# Trueprint(id(s1),id(s2))# 相同地址注意__init__会被调用多次每次实例化时所以初始化逻辑要加保护。3. 使用装饰器实现defsingleton(cls):instances{}defget_instance(*args,**kwargs):ifclsnotininstances:instances[cls]cls(*args,**kwargs)returninstances[cls]returnget_instancesingletonclassMyClass:def__init__(self,value):self.valuevalue# 使用aMyClass(10)bMyClass(20)print(aisb)# Trueprint(a.value)# 10第一次传入的值生效后续忽略4. 使用元类Metaclass实现高级方式classSingletonMeta(type):_instances{}def__call__(cls,*args,**kwargs):ifclsnotincls._instances:instancesuper().__call__(*args,**kwargs)cls._instances[cls]instancereturncls._instances[cls]classDatabaseConnection(metaclassSingletonMeta):def__init__(self):print(Connecting to database...)# 使用db1DatabaseConnection()db2DatabaseConnection()print(db1isdb2)# True5. 线程安全的单例使用锁如果在多线程环境中使用__new__方式建议加锁避免竞争importthreadingclassThreadSafeSingleton:_instanceNone_lockthreading.Lock()def__new__(cls,*args,**kwargs):ifcls._instanceisNone:withcls._lock:# 双重检查Double-Checked Lockingifcls._instanceisNone:cls._instancesuper().__new__(cls)returncls._instance推荐总结方式推荐度线程安全简洁性说明模块导入★★★★★是最高最 Pythonic强烈推荐__new__重写★★★★需加锁高经典方式装饰器★★★是中灵活但参数会被忽略元类★★是低强大但复杂threading.Lock★★★是中多线程必备实际建议99% 的场景下使用模块级单例就够了不要过度设计。如果你真的需要一个“类”的单例行为使用__new__或元类。避免在单例中持有可变全局状态容易导致 bug。如果你想看单例在实际项目中的应用如日志器、配置中心或者结合其他模式如工厂单例可以告诉我