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

news2024/10/5 15:30:41

一、说明

单例是一种创建型设计模式,能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。

(一) 解决问题

维护共享资源(数据库或文件)的访问权限,避免多个实例覆盖同一变量,引发程序崩溃。

(二) 使用场景

  • 数据库连接
  • 文件操作
  • 所有需要维护对象变量一致性的场景

二、结构

  1. 单例 (Singleton) 类声明了一个名为get­Instance获取实例的静态方法来返回其所属类的一个相同实例。单例的构造函数必须对客户端 (Client) 代码隐藏。 调用获取实例方法必须是获取单例对象的唯一方式。

三、伪代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
单例模式
"""

import threading


class 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._instance


class 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 _instance
        with _lock:
            if _instance is None:
                _instance = cls(*args, **kwargs)
        return _instance

    return wrapper


class MyClass:
    a = 1


class MyClass1(Singleton1):
    a = 1


class MyClass2(metaclass=Singleton2):
    a = 1


@singleton
class MyClass3:
    a = 1


if __name__ == '__main__':
    """
    非单例模式
    2 4787260528
    1 4787260480
    
    方法1, 实现__new__方法
    2 4787260336
    2 4787260336
    
    方法2, 实现metaclass
    3 4787260192
    3 4787260192
    
    方法3, 使用装饰器
    4 4787260144
    4 4787260144
    """
    print("非单例模式")
    s1 = MyClass()
    s2 = MyClass()
    s1.a = 2
    print(s1.a, id(s1))
    print(s2.a, id(s2))
    print()

    print("方法1, __new__方法实现")
    s1_1 = MyClass1()
    s1_2 = MyClass1()
    s1_1.a = 2
    print(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 = 3
    print(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 = 4
    print(s3_1.a, id(s3_1))
    print(s3_2.a, id(s3_2))

四、优缺点

优点

  • 实例唯一:单例模式确保某个类只有一个实例,这有助于节省内存,因为只有一个对象实例在内存中。
  • 避免频繁创建和销毁对象:由于单例对象只创建一次,可以减少频繁的创建和销毁对象带来的性能开销。
  • 便于资源管理:单例模式可以确保某个资源或服务在整个应用程序中只有一个实例,方便对资源的统一管理和优化。
  • 提高性能和资源利用率:单例模式可以避免对资源的重复占用,从而提高性能和资源利用率。

缺点

  • 难以测试和调试:由于单例对象是全局唯一的,其行为可能与其他对象存在耦合,导致测试和调试困难。
  • 难以扩展:单例对象通常只有一个实例,如果需要扩展功能或增加复杂性,可能会面临较大的挑战。
  • 线程安全问题:在多线程环境下,如果没有正确地实现线程同步,可能会导致单例对象的实例化出现问题或产生竞态条件。
  • 过度使用可能会产生依赖和耦合:如果过度使用单例模式,可能会导致代码之间的耦合度过高,不利于代码的维护和重构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1420435.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32入门教程-2023版【5-1】中断执行流程

关注 点赞 不错过精彩内容 大家好,我是硬核王同学,最近在做免费的嵌入式知识分享,帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 二、中断执行流程 (1)中断程序的执行流程 左边第一个图中,从上…

【MySQL 流浪之旅】 第六讲 浅谈 MySQL 锁

系列文章目录 【MySQL 流浪之旅】 第一讲 MySQL 安装【MySQL 流浪之旅】 第二讲 MySQL 基础操作【MySQL 流浪之旅】 第三讲 MySQL 基本工具【MySQL 流浪之旅】 第四讲 MySQL 逻辑备份【MySQL 流浪之旅】 第五讲 数据库设计的三个范式 目录 系列文章目录 一、什么是锁&#x…

网络安全|重大失误!微软被盗测试账号拥有公司Office 365管理员权限

微软网络近期遭黑客入侵,高管电子邮件被监视长达两个月。 一位研究员表示,黑客通过获取一个拥有管理员权限的老旧测试帐号的访问权限来实施入侵,这是微软犯下的重大失误。 微软在1月25日(上周四)发布第二篇公告&…

Android Studio项目——TCP客户端

目录 一、TCP客户端UI 1、UI展示 2、xml代码 二、TCP客户端数据发送 三、TCP客户端数据接收 一、TCP客户端UI 1、UI展示 2、xml代码 <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.…

JAVA双列集合Map的特点

一次存一对元素&#xff0c;分别是 键 和 值&#xff0c;他们是一 一对应的&#xff1a;其中&#xff1a;键不可以重复&#xff0c;值可以重复这一对数据叫键值对、键值对对象、或 Entry Map 的体系结构&#xff1a; Map的常见API&#xff1a; 方式的实现&#xff1a;注意 Map …

UDP通信以及本地套接字

1. UDP 1.1 UDP 通信&#xff1a; UDP服务端创建出来的套接字不是监听套接字&#xff0c;直接就是通信套接字。 #include <sys/types.h> #include <sys/socket.h> ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *de…

网络原理-TCP/IP(1)

应用层 我们之前编写完了基本的java socket, 要知道,我们之前所写的所有代码都在应用层中,都是为了完成某项业务,如翻译等.关于应用层,后面会有专门的讲解,在此处先讲一下基础知识. 应用层对应着应用程序,是程序员打交道最多的一层,调用系统提供的网络api写出的代码都是应用层…

正式阶段高等数学复习之不定积分

不定积分这部分是为后面的定积分做准备的&#xff0c;整体上的框架可以分为2&#xff08;定义&#xff09;3&#xff08;计算方式&#xff09;3&#xff08;能积出来的三个函数&#xff09; 1、不定积分的概念&#xff1a;求某一个函数的不定积分就是求这个函数的原函数&#…

DIY_SmartWatch_S3

​​​​​ 简介&#xff1a;成熟的智能手表方案DIY&#xff1b;采用乐鑫ESP32-S3&#xff0c;支持蓝牙和WIFI。240x280彩色LCD触摸屏&#xff1b;内置9D运动睡眠传感器&#xff0c;支持SPI接口扩展在线心率&#xff0c;血氧等健康传感模组&#xff1b;支持USB TypeC&#xff…

第4章 数据表示与特征工程

目录 1. 分类变量1.1 One-Hot编码&#xff08;虚拟变量&#xff09;检查字符串编码的分类数据 1.2 数字可以编码分类变量 2. 分箱、离散化、线性模型与树3. 交互特征与多相似特征4. 单变量非线性变换总结&#xff08;2~4&#xff09;5. 自动化特征选择5.1 单变量统计5.2 基于模…

[GN] 设计模式—— 创建型模式

文章目录 创建型模式单例模式 -- 确保对象唯一性例子优化饿汉式懒汉式 优缺点使用场景 简单工厂模式例子&#xff1a;优化优缺点适用场景 工厂方法模式 -- 多态工厂的实现例子优缺点优化适用场景 抽象工厂模式 -- 产品族的创建例子优缺点适用场景 总结 创建型模式 单例模式 –…

2024年新提出的算法:(凤头豪猪优化器)冠豪猪优化算法Crested Porcupine Optimizer(附Matlab代码)

本次介绍一种新的自然启发式元启发式算法——凤头豪猪优化器(Crested Porcupine Optimizer&#xff0c;CPO)。该成果于2024年1月发表在中科院1区SCI top期刊Knowledge-Based Systems&#xff08;IF 8.8&#xff09;上。 1、简介 受到凤头豪猪&#xff08;CP&#xff09;各种…

驼背的危害,远比您能想到的还要多!

现在的年轻人才20多岁的年纪&#xff0c;就拥有了80多岁的腰椎。 不同于老年人由于骨质疏松而引发的驼背&#xff0c;年轻人驼背大部分是因为工作或学习中长期不正常坐姿导致&#xff0c;也称姿势性驼背。 我们日常工作的时候&#xff0c;习惯性的肩膀前倾去工作&#xff0c;导…

【amis低代码前端框架】vue2集成百度低代码前端框架amis

什么是amis&#xff1a;amis 是一个低代码前端框架&#xff0c;它使用 JSON 配置来生成页面&#xff0c;可以减少页面开发工作量&#xff0c;极大提升效率。 第一步&#xff1a;下载amis 命令行内执行以下命令下载安装amis npm i amis第二步&#xff1a;下载完毕amis后 将nod…

[React源码解析] Fiber (二)

在React15及以前, Reconciler采用递归的方式创建虚拟Dom, 但是递归过程不可以中断, 如果组件的层级比较深的话, 递归会占用线程很多时间, 那么会造成卡顿。 为了解决这个问题, React16将递归的无法中断的更新重构为异步的可中断更新, Fiber架构诞生。 文章目录 1.Fiber的结构2…

在Windows11的WSL上运行Llama2-7b-chat 下

上一篇博客讲了我跑Llama的demo的心路历程&#xff08;上一篇博客传送门&#xff09;&#xff0c;这篇我们主要是讲下怎么配置。 快速开始 使用Linux、Linux、Linux&#xff0c;重要的事情说三遍&#xff0c;如果你和我一样懒得安装双系统&#xff0c;那么在Windows下安装一个…

java组装复杂的map结构

如下图数据库查出来的记录要组装成如下图所示的map结构。 直接上代码 package com.rt.test.other;import org.apache.commons.lang.StringUtils;import java.util.*;public class TestMap {public static void main(String[] args) {Map<String,String> mapnew LinkedHa…

vue 使用 v-viewer 用于图片浏览的Vue组件,支持旋转、缩放、翻转等操作,基于viewer.js。

作者连接 npm&#xff1a; npm install v-viewerlegacy viewerjs main.js 引入&#xff1a; // 引入Viewer插件 import VueViewer, { directive as viewerDirective } from v-viewer; // 引入Viewer插件的图片预览器的样式 import viewerjs/dist/viewer.css; // 使用Viewer图片…

深入Pyecharts:桑基图绘制与炫酷效果实战【第38篇—python:桑基图】

文章目录 深入Pyecharts&#xff1a;桑基图绘制与炫酷效果实战桑基图简介安装 Pyecharts简单桑基图的绘制自定义桑基图的炫酷效果高级样式定制 多组数据桑基图的展示动态桑基图的绘制结合真实数据的桑基图案例导出和分享进阶应用&#xff1a;桑基图与其他图表的组合总结 深入Py…

【Java】创建一个SpringBoot项目

软件版本&#xff1a;IDE专业版 一、创建 创建项目时&#xff0c;要注意的有下面几点 1、 为了使用JDK1.8&#xff0c;我们在创建时用阿里云国服&#xff0c;将Server URL &#xff1a; https://start.spring.io/ 或者http://start.springboot.io/更改为&#xff1a;https:/…