Python单例模式介绍、使用
一、单例模式介绍
-
概念:单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供访问该实例的全局访问点。
-
功能:单例模式的主要功能是确保在应用程序中只有一个实例存在。
-
优势:
- 节省系统资源:由于只有一个实例存在,因此系统的资源占用会比较小。
- 更好的控制全局变量:单例模式可以有效控制全局变量的使用方式,从而更好地维护程序的可维护性和可扩展性。
- 更好的共享资源:由于只有一个实例存在,因此可以更好地共享资源。
-
劣势:
- 单例模式可能会引起代码耦合:由于单例模式只能创建一个实例,因此在程序中可能会出现过度依赖单例模式的情况,这会导致代码的耦合度变高。
- 单例模式可能会导致性能问题:如果单例模式的实例化过程比较复杂,可能会导致性能问题。
-
应用场景:
- 日志处理器:在应用程序中,只需要一个日志处理器来记录所有的日志信息。
- 数据库连接池:在应用程序中,只需要一个数据库连接池来管理所有的数据库连接。
- 全局配置信息:在应用程序中,只需要一个配置信息实例来管理所有的全局配置信息。
总之,单例模式适用于那些需要确保在应用程序中只有一个实例存在的情况,同时需要节省系统资源并且更好地控制全局变量。但同时,我们也需要注意单例模式可能引起的代码耦合和性能问题。
二、单例模实现原理
实现步骤
Python单例模式的实现原理基本与其编语言的单例模式实现原理相同。实现步骤如下:
- 定义一个类变量,用于存储单例实例
- 在初始化方法中,检查类变量是否已经被赋值。如果没有,则创建一个新的实例,并将其赋值给类变量。如果已经有一个实例在类变量中,则返回该实例
- 提供一个静态方法来返回类变量中保存的单例实例
具体来说,单例模式的实现步骤如下:
class Singleton:__instance = Nonedef __init__(self):if Singleton.__instance is None:Singleton.__instance = selfelse:raise Exception("Singleton class instantiated more than once")@staticmethoddef get_instance():if not Singleton.__instance:Singleton()return Singleton.__instance
在上面的代码中,我们定义了一个类变量__instance来保存单例实例,我们通过构造函数__init__来检查该实例是否已经存在。如果不存在,则创建一个新的实例。如果已经存在,则抛出一个异常,防止创建多个实例。
我们还实现了一个静态方法get_instance,该方法返回类变量__instance保存的单例实例。在调用该方法时,我们首先检查类变量__instance是否存在,如果不存在,则创建一个新的实例。否则,我们只返回保存在类变量__instance中的实例。
以下是使用上述代码的示例:
s1 = Singleton.get_instance()
s2 = Singleton.get_instance()assert s1 == s2 # s1 and s2 are equal
由于Singleton模式确保一个类只有一个实例,因此s1和s2应该是相等的。由于它们都是同一个实例,所以它们应该返回True。
静态方法介绍
@staticmethod是Python中的一个装饰器(decorator),它表明该方法是一个静态方法。静态方法是一个与类相关的函数,不依赖于类中的任何实例,因此静态方法可以在不创建类的实例的情况下调用。静态方法可以在类中使用,也可以在类外部使用。
静态方法使用@staticmethod装饰器来声明。例如:
class MyClass:@staticmethoddef my_static_method():print("This is a static method")
在上面的代码中,我们定义了一个MyClass类,并使用@staticmethod装饰器来声明静态方法my_static_method()。在类的实例中,我们可以通过以下方式调用该方法:
my_instance = MyClass()
my_instance.my_static_method()
或者,我们也可以在类外部直接调用该方法:
MyClass.my_static_method()
请注意,与其他编程语言不同,Python中的静态方法可以访问类变量,但不能访问实例变量。
@staticmethod是一个装饰器(decorator),用于声明一个静态方法。静态方法是属于类的方法,而不是属于类的实例的方法。使用@staticmethod装饰器可以使方法不依赖于任何类实例而被调用。
静态方法可以在不需要实例化类的情况下进行调用。在静态方法中,不能访问类中的实例变量或实例方法。如果需要访问类中的属性或方法,则应该使用@classmethod装饰器声明一个类方法。
使用静态方法的主要目的是将方法与类关联,而不是与类的实例关联。因此,在需要在类的实例之间共享方法时,静态方法非常有用。
以下是一个使用@staticmethod装饰器的例子:
class MyClass:@staticmethoddef my_static_method():print("This is a static method")
在上面的代码中,我们定义了一个名为MyClass的类,并使用@staticmethod装饰器声明了一个名为my_static_method()的静态方法。我们可以在类的实例之间共享该方法,或者在类外部直接调用该方法。
my_instance = MyClass()
my_instance.my_static_method()MyClass.my_static_method()
输出结果:
This is a static method
This is a static method
类的实例之间共享方法
在Python中,类的实例之间可以共享方法。这是因为Python中的方法是在类的级别定义的,而不是在实例级别定义的。因此,所有该类的实例都共享相同的方法。
以下是一个示例,其中两个类的实例共享一个简单的方法:
class MyClass:@staticmethoddef my_static_method():print("This is a static method")instance_1 = MyClass()
instance_2 = MyClass()instance_1.my_static_method()
instance_2.my_static_method()
输出结果:
This is a static method
This is a static method
在上面的代码中,我们定义了一个名为MyClass的类,并使用@staticmethod装饰器声明了一个名为my_static_method()的静态方法。我们创建了两个MyClass的实例,并在它们之间共享该方法。
当我们在这两个实例上调用这个方法时,我们会发现它们都打印出了相同的消息,证明了这两个实例之间的方法是共享的。
三、示例
实现全局配置功能
单例模式可以用于实现全局配置信息功能,确保应用程序中的所有模块都使用相同的配置信息,避免冲突和不一致性。
以下是一个简单的示例,演示如何使用单例模式实现全局配置信息功能:
class Config:__instance = None__config_data = {'key1': 'value1', 'key2': 'value2'}def __new__(cls):if cls.__instance is None:cls.__instance = super().__new__(cls)return cls.__instancedef get_config_value(self, key):return self.__config_data.get(key)def set_config_value(self, key, value):self.__config_data[key] = valueconfig1 = Config()
config2 = Config()# Set a new config value using config1
config1.set_config_value('key1', 'new_value1')# Get the config value using config2
print(config2.get_config_value('key1'))
在上面的代码中,我们定义了一个名为 Config 的单例类,并在这个类中定义了一个静态私有变量 __instance,以确保该类的实例只被创建一次。我们还定义了一个名为 __config_data 的私有字典变量,用于存储全局配置信息。
在类定义中,我们使用 __new__() 方法来返回单例实例。如果该类已经有了一个实例,那么以后再次调用 __new__() 方法就会返回这个实例,而不是创建一个新的实例。
我们还定义了两个实例方法,get_config_value() 和 set_config_value(),用于获取和设置配置信息。
在这个示例中,我们创建了两个 Config 类的实例 config1 和 config2。我们先使用 config1 对 key1 进行了设置,然后使用 config2 来获取 key1 的值。我们发现,尽管我们在 config1 对象上进行了更改,但是 config2 对象获取到的值仍然是 value1,证明了这两个实例共享相同的全局配置信息。
实现记录日志功能
假设我们有一个需要记录日志的应用程序,我们希望在整个应用程序中只有一个日志处理器实例,因为多个日志处理器实例会占用系统资源,导致程序运行缓慢。这时我们可以使用Python单例模式来确保应用程序中只有一个日志处理器实例。
具体实现如下:
class Logger:instance = Nonedef __init__(self):if not Logger.instance:Logger.instance = selfelse:self.__dict__ = Logger.instance.__dict__def log(self, message):# 日志记录逻辑pass
在上面的代码中,我们使用了一个类变量instance来保存Singleton类的唯一实例。在每次创建Singleton对象时,我们首先检查类变量是否已经被赋值。如果没有,则创建一个新的实例,并将其赋值给类变量。如果已经有一个实例在类变量instance中,则返回该实例。这样,我们就保证了整个应用程序中只有一个Logger实例存在。
使用上述代码的例子:
logger1 = Logger()
logger2 = Logger()assert logger1 == logger2
由于Singleton模式确保一个类只有一个实例,因此logger1和logger2应该是相等的。由于它们都是同一个实例,所以它们应该返回True。
class MyClass:@staticmethod # @staticmethod装饰器声明了一个名为my_static_method()的静态方法def my_static_method():print("This is a static method")instance_1 = MyClass()
instance_2 = MyClass()# 实例之间共享方法
# 实例1,2 共享了MyClass()类的my_static_method()方法
instance_1.my_static_method()
instance_2.my_static_method()class Singleton:__instance = Nonedef __init__(self):if Singleton.__instance is None:Singleton.__instance = selfelse:raise Exception("Singleton class instantiated more than once")@staticmethoddef get_instance():if not Singleton.__instance:Singleton()return Singleton.__instances1 = Singleton.get_instance()
s2 = Singleton.get_instance()assert s1 == s2 # s1 and s2 are equalclass Logger:instance = Nonedef __init__(self):if not Logger.instance:Logger.instance = selfelse:self.__dict__ = Logger.instance.__dict__def log(self, message):# 日志记录逻辑# print(message)return messagelogger1 = Logger()
logger2 = Logger()
print(logger1.log("log1"))print(logger2.log("log2"))# assert logger1 == logger2#********************* python 单例模式实现全局配置信息功能
class Config:__instance = None__config_data = {'key1': 'value1', 'key2': 'value2'}def __new__(cls):if cls.__instance is None:cls.__instance = super().__new__(cls)return cls.__instancedef get_config_value(self, key):return self.__config_data.get(key)def set_config_value(self, key, value):self.__config_data[key] = valueconfig1 = Config()
config2 = Config()print(config2.get_config_value('key1'))# Set a new config value using config1
config1.set_config_value('key1', 'new_value1') # 设置已有信息
config1.set_config_value('key3', 'new_value3') # 新增信息# Get the config value using config2
print(config2.get_config_value('key1'))
print(config2.get_config_value('key2'))
print(config2.get_config_value('key3'))
运行结果:
This is a static method
This is a static method
log1
log2
value1
new_value1
value2
new_value3
相关文章:
Python单例模式介绍、使用
一、单例模式介绍 概念:单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供访问该实例的全局访问点。 功能:单例模式的主要功能是确保在应用程序中只有一个实例存在。 优势: 节省系统资源:由…...
1334179-85-9,BTTAA,是各种化学生物学实验中生物偶联所需
资料编辑|陕西新研博美生物科技有限公司小编MISSwu BTTAA试剂 | 基础知识概述(部分): 中文名称:2-[4-({双[(1-叔丁基-1H-1,2,3-三唑-4-基)甲基]氨基}甲基)-1H-1,2,3-三唑-1-基]乙酸 英文名称:BTTAA CAS号:1334179-8…...
Linux系统中的SQL语句
本节主要学习,SQL语句的语句类型,数据库操作,数据表操作,和数据操作等。 文章目录 一、SQL语句类型 DDL DML DCL DQL 二、数据库操作 1.查看 2.创建 默认字符集 指定字符集 3.进入 4.删除 5.更改 库名称 字符集 6…...
力扣27 26 283 844 977 移除数组
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的…...
【沐风老师】3DMAX自动材质插件使用方法教程
3DMAX自动材质插件使用方法教程 3DMAX自动材质工具用于在将纹理加载到3dsax中时快速创建简单的材质,并具有一些很酷的材质功能。 这个插件可以根据真正制造商的纹理(通常比例为2:1)快速创建简单的木材材质,并根据板材的长度自动对…...
让你 React 组件水平暴增的 5 个技巧
目录 透传 className、style 通过 forwardRef 暴露一些方法 useCallback、useMemo 用 Context 来跨组件传递值 React.Children、React.cloneElement 总结 最近看了一些 Ant Design 的组件源码,学到一些很实用的技巧,这篇文章来分享一下。 首先&am…...
阿里云部署 ChatGLM2-6B 与 langchain+ChatGLM
1.ChatGLM2-6B 部署 更新系统 apt-get update 安装git apt-get install git-lfs git init git lfs install 克隆 ChatGLM2-6B 源码 git clone https://github.com/THUDM/ChatGLM2-6B.git 克隆 chatglm2-6b 模型 #进入目录 cd ChatGLM2-6B #创建目录 mkdir model #进入目录 cd m…...
F12开发者工具的简单应用
目录 elements 元素 1、元素的定位和修改 2、UI自动化应用 console 控制台 sources 源代码 network 网络 1、定位问题 2、接口测试 3、弱网测试 performance 性能 memory 存储 application 应用 recorder 记录器 界面展示如下(设置中可以切换中英文&am…...
【 Python 全栈开发 - 人工智能篇 - 45 】决策树与随机森林
文章目录 一、概念与原理1.1 决策树1.1.1 概念1.1.2 原理特征选择分割方法 1.1.3 优点与缺点1.1.4 Python常用决策树算法 1.2 随机森林1.2.1 概念1.2.2 原理1.2.3 优点与缺点1.2.4 Python常用随机森林算法 1.3 决策树与随机森林的比较1.3.1 相同之处1.3.2 不同之处 二、决策树算…...
SpringBoot集成kafka全面实战
本文是SpringBootKafka的实战讲解,如果对kafka的架构原理还不了解的读者,建议先看一下《大白话kafka架构原理》、《秒懂kafka HA(高可用)》两篇文章。 一、生产者实践 普通生产者 带回调的生产者 自定义分区器 kafka事务提交…...
新建Git仓库,将本地文件上传至仓库
1、新建仓库,勾选初始化仓库 2、复制仓库链接 3、打开本地文件目录 右键选择 Git Bash Here 打开命令窗口 4、依次按照下面的步骤(*如果报错,看原目录下是否存在 .git 需要删除) // 生成git文件 git init // 把文件加入暂存区 g…...
算法练习——力扣随笔【LeetCode】【C++】
文章目录 LeetCode 练习随笔力扣上的题目和 OJ题目相比不同之处?定义问题排序问题统计问题其他 LeetCode 练习随笔 做题环境 C 中等题很值,收获挺多的 不会的题看题解,一道题卡1 h ,多来几道,时间上耗不起。 力扣上的题…...
web服务器(Tomcat)
目录 一、web服务器 1. 常见web服务器 2. web服务器简介 二、 Apache Tomcat服务器 1. Tomcat服务器简介 2. Tomcat服务器基本使用 3. 启动tomcat常见问题 (1)启动tomcat控制台乱码 (2)启动tomcat闪退问题 (…...
测试方案、功能测试报告、性能测试报告
测试方案内容概要: 项目内容介绍,测试计划安排(人员时间),测试环境(系统配置)需求功能点(内容介绍,测试安排),重点难点场景,系统集成…...
【代码随想录day21】二叉搜索树的最近公共祖先
题目 思路 解题的关键是知道自顶向低递归遍历,第一次遇到root在p和q的区间中时,则root就是p和q的最近公共祖先节点。 递归法 # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val x # …...
ssm文章发布管理系统java小说作品发表jsp源代码mysql
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 ssm文章发布管理系统 系统有2权限:前台账…...
AXI协议之AXILite开发设计(二)
微信公众号上线,搜索公众号小灰灰的FPGA,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 二、AXI-Lite关键代码分析 1、时钟与…...
Qgis二次开发-QgsMapTool地图交互工具详解
1.简介 QgsMapTool地图工具是用于操作地图画布的用户交互式工具。例如,地图平移和缩放功能被实现为地图工具。 QgsMapTool是抽象基类,以下是类的继承关系: 2.常用接口 virtual void canvasDoubleClickEvent (QgsMapMouseEvent *e)重写鼠标…...
MySQL基础(四)数据库备份
目录 前言 一、概述 1.数据备份的重要性 2.造成数据丢失的原因 二、备份类型 (一)、物理与逻辑角度 1.物理备份 2.逻辑备份 (二)、数据库备份策略角度 1.完整备份 2.增量备份 三、常见的备份方法 四、备份(…...
子类化QThread来实现多线程,moveToThread函数的作用
子类化QThread来实现多线程, QThread只有run函数是在新线程里的,其他所有函数都在QThread生成的线程里。正确启动线程的方法是调用QThread::start()来启动。 一、步骤 子类化 QThread;重写run,将耗时的事件放到此函数执行&#…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
