news 2026/4/3 4:32:23

Python 单例模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 单例模式

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:_instance=Nonedef__new__(cls,*args,**kwargs):ifcls._instanceisNone:cls._instance=super().__new__(cls)returncls._instancedef__init__(self):# 注意:__init__ 可能会被调用多次!# 如果需要初始化逻辑,要防止重复执行ifnothasattr(self,'_initialized'):print("Initializing singleton...")self._initialized=True# 测试s1=Singleton()s2=Singleton()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_instance@singletonclassMyClass:def__init__(self,value):self.value=value# 使用a=MyClass(10)b=MyClass(20)print(aisb)# Trueprint(a.value)# 10(第一次传入的值生效,后续忽略)
4. 使用元类(Metaclass)实现(高级方式)
classSingletonMeta(type):_instances={}def__call__(cls,*args,**kwargs):ifclsnotincls._instances:instance=super().__call__(*args,**kwargs)cls._instances[cls]=instancereturncls._instances[cls]classDatabaseConnection(metaclass=SingletonMeta):def__init__(self):print("Connecting to database...")# 使用db1=DatabaseConnection()db2=DatabaseConnection()print(db1isdb2)# True
5. 线程安全的单例(使用锁)

如果在多线程环境中使用__new__方式,建议加锁避免竞争:

importthreadingclassThreadSafeSingleton:_instance=None_lock=threading.Lock()def__new__(cls,*args,**kwargs):ifcls._instanceisNone:withcls._lock:# 双重检查(Double-Checked Locking)ifcls._instanceisNone:cls._instance=super().__new__(cls)returncls._instance
推荐总结
方式推荐度线程安全简洁性说明
模块导入★★★★★最高最 Pythonic,强烈推荐
__new__重写★★★★需加锁经典方式
装饰器★★★灵活但参数会被忽略
元类★★强大但复杂
threading.Lock★★★多线程必备
实际建议
  • 99% 的场景下,使用模块级单例就够了,不要过度设计。
  • 如果你真的需要一个“类”的单例行为,使用__new__或元类。
  • 避免在单例中持有可变全局状态(容易导致 bug)。

如果你想看单例在实际项目中的应用(如日志器、配置中心),或者结合其他模式(如工厂+单例),可以告诉我!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/1 16:55:28

knowledge-grab完整指南:快速下载国家中小学智慧教育资源

knowledge-grab完整指南:快速下载国家中小学智慧教育资源 【免费下载链接】knowledge-grab knowledge-grab 是一个基于 Tauri 和 Vue 3 构建的桌面应用程序,方便用户从 国家中小学智慧教育平台 (basic.smartedu.cn) 下载各类教育资源。 项目地址: http…

作者头像 李华
网站建设 2026/3/30 21:00:22

5分钟快速搭建个人服务器导航中心:Sun-Panel完全使用指南

5分钟快速搭建个人服务器导航中心:Sun-Panel完全使用指南 【免费下载链接】sun-panel 一个NAS导航面板、Homepage、浏览器首页。 项目地址: https://gitcode.com/gh_mirrors/su/sun-panel 想要让你的家庭服务器管理变得更简单高效吗?Sun-Panel作为…

作者头像 李华
网站建设 2026/3/28 22:21:33

为什么你的Open-AutoGLM远程连接总是超时?一文揪出根本原因

第一章:为什么你的Open-AutoGLM远程连接总是超时?一文揪出根本原因远程连接超时是使用 Open-AutoGLM 时最常见的问题之一,尤其在跨区域部署或复杂网络环境下尤为突出。尽管服务端已正常启动,客户端仍频繁遭遇连接中断或响应延迟&a…

作者头像 李华
网站建设 2026/3/15 6:57:47

基于ST7789的可穿戴设备屏幕驱动设计:入门必看

从零开始玩转ST7789:可穿戴设备屏幕驱动的实战指南 你有没有遇到过这样的情况? 花了几百块买来一块号称“高清彩屏”的0.96寸圆形TFT模块,接上STM32后却发现显示花屏、刷新卡顿、功耗爆表……最后只能扔在角落吃灰? 别急——这大…

作者头像 李华
网站建设 2026/3/30 12:39:22

《安卓逆向这档事》demo5 ----正己大佬

demo5 第五关网上找了很多,但是发现关于这一个版本的demo去除教程是一点没有,而且我也找不到原始的demo无法做到IO重定向。所以我也就直接通过jadx分析软件的java代码查找签名校验函数逻辑,然后通过NP管理器打开dex文件修改对应的smail代码&a…

作者头像 李华
网站建设 2026/3/6 14:29:32

智谱Open-AutoGLM插件使用秘籍:5个你不知道的高级技巧,第3个太惊艳

第一章:智谱Open-AutoGLM chrome 插件智谱Open-AutoGLM Chrome插件是一款专为提升网页端自然语言交互效率而设计的浏览器扩展工具。该插件基于AutoGLM大模型技术,集成于Chrome浏览器中,能够在用户浏览网页时实时提供语义理解、内容摘要、智能…

作者头像 李华