当前位置: 首页 > news >正文

Python单例模式介绍、使用

 一、单例模式介绍

  • 概念:单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供访问该实例的全局访问点。

  • 功能:单例模式的主要功能是确保在应用程序中只有一个实例存在。

  • 优势:

    1. 节省系统资源:由于只有一个实例存在,因此系统的资源占用会比较小。
    2. 更好的控制全局变量:单例模式可以有效控制全局变量的使用方式,从而更好地维护程序的可维护性和可扩展性。
    3. 更好的共享资源:由于只有一个实例存在,因此可以更好地共享资源。
  • 劣势:

    1. 单例模式可能会引起代码耦合:由于单例模式只能创建一个实例,因此在程序中可能会出现过度依赖单例模式的情况,这会导致代码的耦合度变高。
    2. 单例模式可能会导致性能问题:如果单例模式的实例化过程比较复杂,可能会导致性能问题。
  • 应用场景:

    1. 日志处理器:在应用程序中,只需要一个日志处理器来记录所有的日志信息。
    2. 数据库连接池:在应用程序中,只需要一个数据库连接池来管理所有的数据库连接。
    3. 全局配置信息:在应用程序中,只需要一个配置信息实例来管理所有的全局配置信息。

总之,单例模式适用于那些需要确保在应用程序中只有一个实例存在的情况,同时需要节省系统资源并且更好地控制全局变量。但同时,我们也需要注意单例模式可能引起的代码耦合和性能问题。

二、单例模实现原理

实现步骤

Python单例模式的实现原理基本与其编语言的单例模式实现原理相同。实现步骤如下:

  1. 定义一个类变量,用于存储单例实例
  2. 在初始化方法中,检查类变量是否已经被赋值。如果没有,则创建一个新的实例,并将其赋值给类变量。如果已经有一个实例在类变量中,则返回该实例
  3. 提供一个静态方法来返回类变量中保存的单例实例

具体来说,单例模式的实现步骤如下:

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 类的实例 config1config2。我们先使用 config1key1 进行了设置,然后使用 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.增量备份 三、常见的备份方法 四、备份&#xff08…...

子类化QThread来实现多线程,moveToThread函数的作用

子类化QThread来实现多线程, QThread只有run函数是在新线程里的,其他所有函数都在QThread生成的线程里。正确启动线程的方法是调用QThread::start()来启动。 一、步骤 子类化 QThread;重写run,将耗时的事件放到此函数执行&#…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制&#xff0…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...

篇章二 论坛系统——系统设计

目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...