【Python笔记-设计模式】单例模式

一、说明
单例是一种创建型设计模式,能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
(一) 解决问题
维护共享资源(数据库或文件)的访问权限,避免多个实例覆盖同一变量,引发程序崩溃。
(二) 使用场景
- 数据库连接
- 文件操作
- 所有需要维护对象变量一致性的场景
二、结构

- 单例 (Singleton) 类声明了一个名为
getInstance获取实例的静态方法来返回其所属类的一个相同实例。单例的构造函数必须对客户端 (Client) 代码隐藏。 调用获取实例方法必须是获取单例对象的唯一方式。
三、伪代码
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
单例模式
"""import threadingclass Singleton1:"""方法1, 实现__new__方法并在将一个类的实例绑定到类变量_instance上,如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回如果cls._instance不为None,直接返回cls._instance"""_instance = None_lock = threading.Lock()def __new__(cls, *args, **kwargs):with cls._lock:if not cls._instance:cls._instance = super().__new__(cls)return cls._instanceclass Singleton2(type):"""方法2,实现metaclass,利用metaclass在实例化时已经创建好实例,从而实现单例模式,注意必须通过metaclass实现"""_instances = {}_lock = threading.Lock()def __call__(cls, *args, **kwargs):with cls._lock:if cls not in cls._instances:cls._instances[cls] = super().__call__(*args, **kwargs)return cls._instances[cls]def singleton(cls):"""方法3,使用装饰器"""_instance = None_lock = threading.Lock()def wrapper(*args, **kwargs):nonlocal _instancewith _lock:if _instance is None:_instance = cls(*args, **kwargs)return _instancereturn wrapperclass MyClass:a = 1class MyClass1(Singleton1):a = 1class MyClass2(metaclass=Singleton2):a = 1@singleton
class MyClass3:a = 1if __name__ == '__main__':"""非单例模式2 47872605281 4787260480方法1, 实现__new__方法2 47872603362 4787260336方法2, 实现metaclass3 47872601923 4787260192方法3, 使用装饰器4 47872601444 4787260144"""print("非单例模式")s1 = MyClass()s2 = MyClass()s1.a = 2print(s1.a, id(s1))print(s2.a, id(s2))print()print("方法1, __new__方法实现")s1_1 = MyClass1()s1_2 = MyClass1()s1_1.a = 2print(s1_1.a, id(s1_1))print(s1_2.a, id(s1_2))print()print("方法2, metaclass实现")s2_1 = MyClass2()s2_2 = MyClass2()s2_1.a = 3print(s2_1.a, id(s2_1))print(s2_2.a, id(s2_2))print()print("方法3, 使用装饰器")s3_1 = MyClass3()s3_2 = MyClass3()s3_1.a = 4print(s3_1.a, id(s3_1))print(s3_2.a, id(s3_2))
四、优缺点
优点
- 实例唯一:单例模式确保某个类只有一个实例,这有助于节省内存,因为只有一个对象实例在内存中。
- 避免频繁创建和销毁对象:由于单例对象只创建一次,可以减少频繁的创建和销毁对象带来的性能开销。
- 便于资源管理:单例模式可以确保某个资源或服务在整个应用程序中只有一个实例,方便对资源的统一管理和优化。
- 提高性能和资源利用率:单例模式可以避免对资源的重复占用,从而提高性能和资源利用率。
缺点
- 难以测试和调试:由于单例对象是全局唯一的,其行为可能与其他对象存在耦合,导致测试和调试困难。
- 难以扩展:单例对象通常只有一个实例,如果需要扩展功能或增加复杂性,可能会面临较大的挑战。
- 线程安全问题:在多线程环境下,如果没有正确地实现线程同步,可能会导致单例对象的实例化出现问题或产生竞态条件。
- 过度使用可能会产生依赖和耦合:如果过度使用单例模式,可能会导致代码之间的耦合度过高,不利于代码的维护和重构。
相关文章:
【Python笔记-设计模式】单例模式
一、说明 单例是一种创建型设计模式,能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。 (一) 解决问题 维护共享资源(数据库或文件)的访问权限,避免多个实例覆盖同一变量,引发程序崩溃。 …...
Java使用io流生成pdf文件
首先生成pdf和正常请求接口一样,直接写~ Controller层: 第一个注解:最顶层增加 Controller 注解(控制器)不多讲了 直接加上。 第二个注解:最顶层增加 CrossOrigin 注解此注解是为了浏览器请求的时候防…...
STL-priority_queue
文档 目录 1.关于priority_queued1的定义 2.priority_queue的使用 1.关于priority_queued1的定义 1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。 2. 此上下文类似于堆,在堆中可以随时插入元…...
SpringBoot基于注解形式配置多数据源@DS
TOC() 1.引入依赖 <!-- dynamic-datasource 多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.2</version></dependency>2.配置…...
华清远见作业第三十四天——C++(第三天)
思维导图: 题目: 设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数和拷贝构造函数。 代码&#…...
Shell中正则表达式
1.正则表达式介绍 1、正则表达式---通常用于判断语句中,用来检查某一字符串是否满足某一格式 2、正则表达式是由普通字符与元字符组成 3、普通字符包括大小写字母、数字、标点符号及一些其他符号 4、元字符是指在正则表达式中具有特殊意义的专用字符,…...
Flutter Canvas 属性详解与实际运用
在Flutter中,Canvas是一个强大的绘图工具,允许我们以各种方式绘制图形、文字和图像。了解Canvas的属性是开发高度定制化UI的关键。在本篇博客中,我们将深入探讨Flutter中Canvas的一些重要属性,并展示它们在实际应用中的使用。 1.…...
Django配置websocket时的错误解决
基于移动群智感知的网络图谱构建系统需要手机app不断上传数据到服务器并把数据推到前端标记在百度地图上,由于众多手机向同一服务器发送数据,如果使用长轮询,则实时性差、延迟高且服务器的负载过大,而使用websocket则有更好的性能…...
(免费分享)springboot,vue在线考试系统
springboot 在线考试系统 前后端分离 一、项目简介 基于SpringBoot的在线考试系统 二、技术实现 后台框架:SpringBoot,mybatis-plus UI界面:Vue、ElementUI、Axios、Node.js(前后端分离) 数据库:MySQ…...
WebSocket 整合 记录用法
WebSocket 介绍 WebSocket 是基于tcp的一种新的网络协议,可以让浏览器 和 服务器进行通信,然后区别于http需要三次握手,websocket只用一次握手,就可以创建持久性的连接,并进行双向数据传输 Http和WebSocket的区别 Http是短连接,WebSocket’是长连接Http通信是单向的,基于请求…...
推荐5个我常用的软件,简单高效
今天给大家推荐5个我自己也常用的软件,可以解决很多问题,给你的学习和办公带来巨大帮助。 1.快速启动——Keypirinha Keypirinha是一款快速启动软件,可以让用户通过输入关键词来快速打开程序、文件、网页、搜索引擎等。Keypirinha支持…...
代码随想录训练营第三十一天|122.买卖股票的最佳时机II55.跳跃游戏45.跳跃游戏II
122.买卖股票的最佳时机II class Solution { public:int maxProfit(vector<int>& prices) {int earn0;for(int i 0; i < prices.size()-1;i){int x prices[i 1] - prices[i];if(x>0){earnx;}}return earn;} }; 55.跳跃游戏 本题关键在于看覆盖的范围 利…...
python17-Python的字符串格式化
Python提供了“%”对各种类型的数据进行格式化输出,例如如下代码。 # !/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2024/01# @Author : Laopiweight = 180print(老师傅的体重是 %s % weight) 上面程序就是格式化输出的关键代码,这行代码中的 print 函数包含三个部…...
HTTPS 之fiddler抓包--jmeter请求
一、浅谈HTTPS 我们都知道HTTP并非是安全传输,在HTTPS基础上使用SSL协议进行加密构成的HTTPS协议是相对安全的。目前越来越多的企业选择使用HTTPS协议与用户进行通信,如百度、谷歌等。HTTPS在传输数据之前需要客户端(浏览器)与服…...
Kotlin快速入门系列6
Kotlin的接口与扩展 接口 与Java类似,Kotlin使用interface关键字定义接口,同时允许方法有默认实现: interface KtInterfaceTest {fun method()fun methodGo(){println("上面方法未实现,此方法已实现")} } 接口实现 …...
w24文件上传之PHP伪协议
PHP支持的伪协议 file:// - 访问本地文件系统 http:// - 访问网址 ftp:// - 访问文件 php:// -访问各个输入/输出流 zlib:// -压缩流 data:// - 数据 glob:// -查找匹配的文件路径模式 phar:// - php归档 ssh2:// - Secure shell 2 rar:// - RAR ogg:// - 音频流 expect:// - …...
SQL注入攻击 - 基于时间的盲注
环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 1、SQL 盲注基础 盲注(Blind SQL)是注入攻击的一种形式,攻击者通过向数据库发送true或false等问题,并根据应用程序返回的信息来判断结果。这种攻击方式出现的原因是应用程序配…...
比VS Code快得多
Zed 是一款支持多人协作的代码编辑器,底层采用 Rust,且默认支持 Rust,还自带了 rust-analyzer,主打“高性能”。1 月 24 日,备受关注的 Zed 项目宣布正式开源。 Zed 代码库将采用 Copyleft 许可证,其中编辑…...
将一个excel文件里面具有相同参数的行提取后存入新的excel
功能描述: 一个excel里面有很多行数据,其中“交易时间”这一列有很多交易日期,有些行的交易日期是一样的,那么就把所有交易日期相同的行挑出来,形成一个新的以交易日期命名的文件。import pandas as pd import os# 读取…...
Linux下安装edge
edge具有及其强大的功能,受到很多人的喜爱,它也开发Linux版本,下面是安装方法: 1.去edge官网下载Linux(.deb)文件。 https://www.microsoft.com/zh-cn/edge/download?formMA13FJ 2.下载之后输入以下指令(后面是安装…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...
