独一无二的设计模式——单例模式(python实现)
1. 引言
大家好,今天我们来聊聊设计模式中的“独一无二”——单例模式。想象一下,我们在开发一个复杂的软件系统,需要一个全局唯一的配置管理器,或者一个统一的日志记录器;如果每次使用这些功能都要创建新的实例,不仅浪费资源,还可能导致数据不一致,那么,我们该怎么办呢?这时候,单例模式就派上用场啦!今天,我将带大家深入了解单例模式的概念、实现方法以及实际应用。准备好了吗?Let’s go!
2. 什么是单例模式
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。就像世界上只有一个太阳,我们也希望某些对象在整个应用程序中只有一个实例。单例模式适用于需要全局唯一访问的资源,如数据库连接、配置管理器、日志记录器等。
3. 单例模式的实现
基本实现
在Python中,实现单例模式有多种方法,以下是一些经典的方法:
使用__new__方法,这是实现单例模式的常见方法之一:
class Singleton:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)return cls._instancedef __init__(self):self.data = "This is the singleton instance"
使用装饰器,装饰器可以让实现单例模式更加简洁和复用:
def singleton(cls):instances = {}def get_instance(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return get_instance@singleton
class Singleton:def __init__(self):self.data = "This is the singleton instance"
使用元类,元类控制类的创建过程,可以用来实现单例模式:
class SingletonMeta(type):_instances = {}def __call__(cls, *args, **kwargs):if cls not in cls._instances:cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)return cls._instances[cls]class Singleton(metaclass=SingletonMeta):def __init__(self):self.data = "This is the singleton instance"
改进的实现
多线程环境中的线程安全,为了在多线程环境中确保线程安全,可以使用线程锁:
import threadingclass Singleton:_instance = None_lock = threading.Lock()def __new__(cls, *args, **kwargs):with cls._lock:if not cls._instance:cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)return cls._instancedef __init__(self):self.data = "This is the singleton instance"
详细代码解析:
_instance类变量用于存储单例实例,它在类的整个生命周期内唯一;__new__方法是实例创建的关键,当_instance为空时,调用父类的__new__方法创建实例并保存到_instance中;__init__方法初始化实例的数据,虽然__init__方法在每次创建实例时都会被调用,但由于我们只创建一次实例,重复调用__init__不会影响单例的状态;singleton是一个装饰器函数,用于装饰目标类cls;SingletonMeta是一个元类,用于控制Singleton类的实例化过程;_lock是一个线程锁,用于确保在多线程环境下,只有一个线程能够创建实例;with cls._lock语句在__new__方法中使用锁,确保只有一个线程能够进入创建实例的代码块。
4. 单例模式的应用场景和实例
示例一:配置文件管理
在应用程序中,配置文件通常需要全局访问且不应被重复加载,使用单例模式可以确保配置管理器只有一个实例,从而避免重复加载配置文件:
class ConfigurationManager(Singleton):def __init__(self):if not hasattr(self, 'config'):self.config = {}def set_config(self, key, value):self.config[key] = valuedef get_config(self, key):return self.config.get(key, None)
使用示例:
config_manager = ConfigurationManager()
config_manager.set_config("api_url", "https://api.example.com")
print(config_manager.get_config("api_url"))
示例二:日志记录
日志记录器是单例模式的经典应用之一,通过确保日志记录器的唯一性,我们可以统一管理日志输出,避免多个日志实例之间的混乱:
import loggingclass Logger(Singleton):def __init__(self):if not hasattr(self, 'logger'):self.logger = logging.getLogger('singleton_logger')handler = logging.StreamHandler()formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')handler.setFormatter(formatter)self.logger.addHandler(handler)self.logger.setLevel(logging.INFO)def log(self, message):self.logger.info(message)
使用示例:
logger = Logger()
logger.log("This is a log message.")
5. 单例模式的优缺点
优点
- 控制实例数量:确保一个类只有一个实例,节省资源;
- 全局访问点:提供一个全局访问点,方便管理和使用。
缺点
- 不易扩展:由于单例模式限制了实例的数量,可能不利于扩展;
- 隐藏依赖关系:单例模式通过全局访问点使用实例,可能导致代码依赖关系不明确,不利于测试。
6. 图示
- 带线程锁的单例模式的UML图:
+----------------+
| Singleton |
+----------------+
| - _instance |
| - _lock |
+----------------+
| + getInstance()|
+----------------+
- 单例模式的示意图:

7. 总结
单例模式是一种简单而强大的设计模式,确保一个类只有一个实例,并提供全局访问点。在实际开发中,单例模式广泛应用于配置管理、日志记录等场景,通过合理地使用单例模式,我们可以有效管理和优化资源,确保系统的一致性和稳定性。
希望今天的分享能让大家对单例模式有更深入的理解,如果你在项目中也使用了单例模式,欢迎留言分享你的经验和见解!

相关文章:
独一无二的设计模式——单例模式(python实现)
1. 引言 大家好,今天我们来聊聊设计模式中的“独一无二”——单例模式。想象一下,我们在开发一个复杂的软件系统,需要一个全局唯一的配置管理器,或者一个统一的日志记录器;如果每次使用这些功能都要创建新的实例&…...
第二证券:可转债基础知识?想玩可转债一定要搞懂的交易规则!
可转债,全称是“可转化公司债券”,是上市公司为了融资,向社会公众所发行的一种债券,具有股票和债券的双重特点,投资者可以选择按照发行时约定的价格将债券转化成公司一般股票,也可作为债券持有到期后收取本…...
原型模式的实现
1. 引言 1.1 背景 在实际编程中,有时需要频繁创建多个相似但稍有不同的对象。如果采用传统的对象创建方式,容易造成代码冗余,对象重复初始化操作也可能带来大量的的资源消耗(如时间、内存等)。这样不仅降低了灵活性,导致难以适应状态的变化,还降低了代码的可扩展性。 …...
【第二套】华为 2024 年校招-硬件电源岗
1.为了避免 50Hz 的电⽹电压⼲扰放⼤器,应该⽤那种滤波器: A.带阻滤波器 B.带通滤波器 C.低通滤波器 D.⾼通滤波器 2.PID 中的 I 和 D 的作⽤分别是? A、消除静态误差和提⾼动态性能 B、消除静态误差和减⼩调节时间 C、提⾼动态性能和减⼩超调…...
Xilinx FPGA:vivado利用单端RAM/串口传输数据实现自定义私有协议
一、项目要求 实现自定义私有协议,如:pc端产生数据:02 56 38 ,“02”代表要发送数据的个数,“56”“38”需要写进RAM中。当按键信号到来时,将“56”“38”读出返回给PC端。 二、信号流向图 三、状态…...
Spark on k8s 源码解析执行流程
Spark on k8s 源码解析执行流程 1.通过spark-submit脚本提交spark程序 在spark-submit脚本里面执行了SparkSubmit类的main方法 2.运行SparkSubmit类的main方法,解析spark参数,调用submit方法 3.在submit方法里调用doRunMain方法,最终调用r…...
粤港联动,北斗高质量国际化发展的重要机遇
今年是香港回归27周年,也是《粤港澳大湾区发展规划纲要》公布5周年,5年来各项政策、平台不断为粤港联动增添新动能。“十四五”时期的粤港澳大湾区,被国家赋予了更重大的使命,国家“十四五”《规划纲要》提出,以京津冀…...
Chrome导出cookie的实战教程
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...
视频文字转语音经验笔记
自媒体视频制作的一些小经验,分享给大家。 一、音频部分: 1、文字转语音阐述: 微软语音识别 云希-青年男, 0.5-0.8变速 。注:云泽-中年男(不支持长音频录制), 适合郑重场合&#…...
视频融合共享平台LntonCVS统一视频接入平台智慧安防应用方案
安防视频监控平台LntonCVS是一款拥有强大拓展性和灵活部署能力的综合管理平台。它支持多种主流标准协议,包括国标GB28181、RTSP/Onvif、RTMP等,同时兼容各厂家的私有协议和SDK,如海康Ehome、海大宇等。LntonCVS不仅具备传统安防视频监控功能&…...
使用Python绘制动态螺旋线:旋转动画效果
文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame绘制螺旋线函数主循环 完整代码 引言 螺旋线是一个具有美学和数学魅力的图形。通过编程,我们可以轻松创建动态旋转的螺旋线动画。在这篇博客中,我们将使用Python和Pygame库来实现…...
Symfony实战手册:PHP框架的高级应用技巧
引言 Symfony是一个功能强大且广泛应用于PHP应用程序开发的框架,它提供了许多高级特性和工具,可以帮助开发人员更高效地构建和管理复杂的Web应用程序。以下是Symfony框架的几个关键方面及其高级应用技巧: 1. 路由和控制器 Symfony的路由组…...
TOGAF培训什么内容?参加TOGAF培训有什么好处?考试通过率多少?
TOGAF培训什么内容?参加TOGAF培训有什么好处?考试通过率多少? TOGAF培训哪些内容? 通过本课程,你将掌握TOGAF的理论和实践,理解企业架构的影响,能够评估、启动、设 计、执行新一轮企业和IT架构…...
keepalived HA nginx方案
安装 centos: yum -y install epel-release yum -y install nginx keepalivedkeepalived配置解析 /etc/keepalived/keepalived.conf ! Configuration File for keepalived # 全局变量 global_defs {router_id nginx_ha # 主从保持一致script_user root # 执行健康检查的…...
报错:pathspec ‘xxx‘ did not match any file(s) known to git
在 escode 中进行分支切换时报如下错误 PS > git checkout xxx error: pathspec xxx did not match any file(s) known to git远程分支已经在 gitlab 客户端手动创建,在 escode 中也使用了拉取之类的操作,但是切换分支时依然报错。 解决方案 查看分…...
sed 保持空间命令之 x 的执行逻辑
目录 1. 将模式空间和保持空间的内容互换并打印 2. 将保持空间的内容交换回模式空间 3. 使用保持空间保存状态信息 4. 交换模式空间与保持空间隔行匹配 sed 有两个内置的缓存空间: 模式空间:该空间是 sed 内置的一个缓冲区,是 sed 执行的…...
按位异或^
在 Python 中,a ^ b 表示按位异或运算符。按位异或运算符对整数的每一位进行运算,如果对应位上的两个二进制数字不同,则结果为 1,否则为 0。 示例 a 5 # 二进制: 0101 b 3 # 二进制: 0011result a ^ b print(result) # 输…...
《企业实战分享 · 常用运维中间件》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,如需交流ÿ…...
PyCharm 2024.1简介
PyCharm 2024.1 是JetBrains公司发布的Python集成开发环境(IDE)的最新版本。作为一个深受开发者欢迎的工具,PyCharm以其强大的功能和高效的开发体验著称。以下是PyCharm 2024.1的主要特性和改进: 1. **性能提升**: …...
终身免费的Navicat数据库,不需要破解,官方支持
终身免费的Navicat数据库,不需要破解,官方支持 卸载了Navicat,很不爽上干货,Navicat免费版下载地址 卸载了Navicat,很不爽 公司不让用那些破解的数据库软件,之前一直使用Navicat。换了几款其他的数据库试了…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
