尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python面向对象:单例模式的多种Python实现方式
一、开篇只能有一个实例的类单例模式Singleton是最常用的设计模式之一保证一个类只有一个实例并提供全局访问点。典型的场景包括数据库连接池、配置管理器、日志器、应用状态管理器。⌨️ 先看一个直观的需求# 问题全局配置应该只有一个实例# 如果每个模块都创建新的Config对象配置就会不一致# ❌ 多个实例——配置不一致# config1 AppConfig() # debugTrue# config2 AppConfig() # debugFalse —— 这是另一个配置了# ✅ 单例——只有一个实例# config1 AppConfig() # 创建实例# config2 AppConfig() # 返回同一个实例# config1 is config2 # True —— 同一个对象二、Python实现单例的四种方式2.1 使用__new__最常用classSingleton:单例——通过__new__控制实例创建_instanceNonedef__new__(cls,*args,**kwargs):ifcls._instanceisNone:cls._instancesuper().__new__(cls)cls._instance._initializedFalsereturncls._instancedef__init__(self,valueNone):# ⚠️ __init__每次都会调用需要防护ifself._initialized:returnself.valuevalue self._initializedTrue# 测试s1Singleton(第一次)s2Singleton(第二次)print(s1iss2)# True —— 同一个实例print(s1.value)# 第一次 —— __init__只执行了一次print(s2.value)# 第一次2.2 使用装饰器defsingleton(cls):单例装饰器——包装类instances{}defget_instance(*args,**kwargs):ifclsnotininstances:instances[cls]cls(*args,**kwargs)returninstances[cls]returnget_instancesingletonclassDatabase:数据库连接——单例def__init__(self,connection_stringdefault):self.connection_stringconnection_stringprint(f创建数据库连接:{connection_string})# 测试db1Database(mysql://localhost/mydb)db2Database(postgresql://localhost/testdb)print(db1isdb2)# Trueprint(db1.connection_string)# mysql://localhost/mydbprint(db2.connection_string)# mysql://localhost/mydb# ⚠️ 装饰器方式的缺点# Database现在是一个函数而不是类print(type(Database))# class function# isinstance检查不适用2.3 使用元类最彻底的实现classSingletonMeta(type):单例元类——自动让类成为单例_instances{}def__call__(cls,*args,**kwargs):ifclsnotincls._instances:cls._instances[cls]super().__call__(*args,**kwargs)returncls._instances[cls]classConfig(metaclassSingletonMeta):配置管理器——单例通过元类def__init__(self,debugFalse):# 不需要_initialized防护——元类控制__init__只调用一次self.debugdebug self.settings{}print(fConfig初始化: debug{debug})# 测试c1Config(debugTrue)c2Config(debugFalse)print(c1isc2)# Trueprint(c1.debug)# True —— 第一次初始化的值print(c2.debug)# True# 元类方式最优雅——类定义时就决定了单例行为# __init__自动只执行一次2.4 使用模块Pythonic方式# Python的模块本身就是单例# 模块在第一次导入时执行之后被缓存到sys.modules# 这是最Pythonic的单例实现方式# config.py class AppConfig: def __init__(self): self.debug False self.host localhost self.port 8080 def set_debug(self, enabled): self.debug enabled # 在模块级别创建实例——这就是单例 config AppConfig() # main.py # from config import config## # 所有地方导入的都是同一个config对象# config.set_debug(True)## # 另一个文件# from config import config# print(config.debug) # True —— 同一个对象# 优点简单、不需要任何特殊语法# 缺点导入时即创建不能延迟、无法传参构造三、单例的实战应用3.1 日志管理器importthreadingfromdatetimeimportdatetimeclassLogger(metaclassSingletonMeta):日志管理器——全局唯一def__init__(self):self._lockthreading.Lock()self._handlers[]self._levelINFOdefset_level(self,level):self._levelleveldefadd_handler(self,handler):self._handlers.append(handler)deflog(self,message,levelINFO):线程安全的日志记录withself._lock:timestampdatetime.now().strftime(%Y-%m-%d %H:%M:%S.%f)[:-3]log_entryf[{timestamp}] [{level}]{message}# 输出到所有处理器forhandlerinself._handlers:handler(log_entry)# 默认输出到控制台ifnotself._handlers:print(log_entry)# 使用——在任何地方获取同一个Loggerdefsome_function():loggerLogger()logger.log(函数执行中...)defanother_function():loggerLogger()logger.log(另一个函数执行中...,levelWARNING)some_function()another_function()3.2 数据库连接池fromthreadingimportLockclassConnectionPool(metaclassSingletonMeta):数据库连接池——全局唯一def__init__(self,max_connections10):self.max_connectionsmax_connections self._connections[]self._in_useset()self._lockLock()print(f连接池创建: 最大{max_connections}个连接)defget_connection(self):获取一个连接withself._lock:iflen(self._connections)self.max_connections:connf连接-{len(self._connections)1}self._connections.append(conn)else:raiseRuntimeError(连接池已满)self._in_use.add(conn)returnconndefrelease_connection(self,conn):释放连接withself._lock:self._in_use.discard(conn)defstatus(self):return{total:len(self._connections),in_use:len(self._in_use),available:len(self._connections)-len(self._in_use),}# 使用poolConnectionPool(max_connections5)conn1pool.get_connection()conn2pool.get_connection()print(pool.status())# {total: 2, in_use: 2, available: 0}pool.release_connection(conn1)print(pool.status())# {total: 2, in_use: 1, available: 1}四、总结单例模式保证只有一个实例。Python提供了多种实现——从简单的模块到彻底的元类。四种实现对比方式优点缺点__new__简单直观需要防__init__重复装饰器简洁类型变成函数元类最彻底稍复杂模块最Pythonic不能延迟创建✅日常推荐模块级别实例最简单→__new__方式需要传参→ 元类框架/库。
RELATED

相关推荐

终于微信也能接入OpenClaw了,附手把手教程和案例,感兴趣的可以看看

终于微信也能接入OpenClaw了,附手把手教程和案例,感兴趣的可以看看

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/2 23:16:25
Cursor 报错排查指南:用 TaoToken 统一 Key 打通 API 配置

Cursor 报错排查指南:用 TaoToken 统一 Key 打通 API 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/2 23:16:25
Codex Plugin 教程:Marketplace、Plugin、Skill 是如何被识别和加载的?TaoToken 统一 Key 通道配置解析

Codex Plugin 教程:Marketplace、Plugin、Skill 是如何被识别和加载的?TaoToken 统一 Key 通道配置解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/2 23:16:25
MORE NEWS

更多资讯

📰

三兴化工的技术实力如何

三兴化工是一家专注纺织印染助剂研发、生产、出口一体化的源头工厂,深耕纺织助剂行业十六年,以自主研发的八大系列印染化工助剂服务国内外印染、毛纺、牛仔、皮革企业。在助剂行业,技术实力直接决定产品品质的稳定性与定制的可行性。三兴化工…

📰

如何判断两本书的规则能否同时使用?agent-rules-books的CHECK_COMPATIBILITY工作流实战

如何判断两本书的规则能否同时使用?agent-rules-books的CHECK_COMPATIBILITY工作流实战 【免费下载链接】agent-rules-books AGENTS.md rules / skills for AI coding agents: Codex, Cursor & Claude Code. Inspired by Clean Code, Refactoring, DDD, Clean A…

📰

江西靠谱的木门外贸出口供应商 源头工厂口碑力荐

木门外贸出口选品避坑指南:如何找到靠谱源头工厂选木门外贸出口订单,本质是选一套能适配海外市场标准、稳定交付且能守住利润的供应链。很多外贸采购商前期都会遇到相同的困惑:市面上的木门厂要么资质不全没法走正规报关,要么工艺…

📰

Atomic Agent部署与打包指南:Node SEA构建单文件可执行与多平台发布矩阵

Atomic Agent部署与打包指南:Node SEA构建单文件可执行与多平台发布矩阵 【免费下载链接】atomic-agent Atomic Agent is a local-first AI agent. Runs open-weight models on your own machine via llama.cpp. 项目地址: https://gitcode.com/gh_mirrors/at/ato…

📰

主流 AI 编程助手对比:2026 年技术选型建议与 TaoToken 统一接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

香河艺皓家具厂:正规源头工厂,酒店餐饮家具综合实力推荐

工程家具采购先搞懂这三点,少踩80%的坑很多商家在找工程家具供应商时,总会陷入找小作坊怕不靠谱,找贸易商怕加价的两难境地。尤其是酒店、餐饮、宿舍这类B端采购,家具不是单一产品,而是要和装修进度、品牌形象、使用场…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬