单例模式(Singleton)

ops/2024/11/19 13:47:39/

一、单例模式

1、相关知识:

        内容:保证一个类只有一个实例,并提供一个访问它的全局访问点;其保证了在程序的不同位置都可以且仅可以取到同一个对象实例。

        使用场景:当类只能有一个实例而且用户从多个地方访问同一个类的实例。

        举个例子来说: 比如你开发一款游戏软件,游戏中需要有“场景管理器”这样一种东西,用来管理游戏场景的切换、资源载入、网络连接等等任务。这个管理器需要有多种方法和属性,在代码中很多地方会被调用,且被调用的必须是同一个管理器,否则既容易产生冲突,也会浪费资源。这种情况下,单例模式就是一个很好的实现方法。

例如:

        Python的logger就是一个单例模式,用以日志记录;

        Windows的资源管理器是一个单例模式

        线程池,数据库连接池等资源池一般也用单例模式

        网站计数器;

优点:

        1、只有一个实例占用资源,并且只需初始化一次;

        2、对唯一实例的受控访问;

 2、实现方式:

(1)、使用函数装饰器实现单例:

def singleton(cls):_instance = {}def inner():if cls not in _instance:_instance[cls] = cls()return _instance[cls]return inner@singleton
class Cls(object):def __init__(self):passcls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2)) 

# 输出结果:

True

(2)、使用类装饰器实现单例:

class Singleton(object):def __init__(self, cls):self._cls = clsself._instance = {}def __call__(self):if self._cls not in self._instance:self._instance[self._cls] = self._cls()return self._instance[self._cls]@Singleton
class Cls2(object):def __init__(self):passcls1 = Cls2()
cls2 = Cls2()
print(id(cls1) == id(cls2))

# 输出结果:    

True

(3)、使用 new 关键字实现单例模式

class Single(object):_instance = Nonedef __new__(cls, *args, **kw):if cls._instance is None:cls._instance = object.__new__(cls, *args, **kw)return cls._instancedef __init__(self):passsingle1 = Single()
single2 = Single()
print(id(single1) == id(single2))

# 输出结果:

True

(4)、使用 metaclass 实现单例模式

class Singleton(type):_instances = {}def __call__(cls, *args, **kwargs):if cls not in cls._instances:cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)return cls._instances[cls]class Cls4(metaclass=Singleton):passcls1 = Cls4()
cls2 = Cls4()
print(id(cls1) == id(cls2))

# 输出结果:

True


http://www.ppmy.cn/ops/134987.html

相关文章

Ekman理论回归

Scientific reportsEkman revisited: Surface currents to the left of the winds in the Northern HemisphereVagn Walfrid Ekman1905年的理论描述了地球旋转受到风的作用,摩擦边界层中的流场,北半球总是在海表风的右侧,南半球总是在海表风的…

使用 OpenAI 提高 Appium 测试脚本效率:从优化到跨平台支持

#自动化测试工程师在使用 Appium 进行移动端测试时,经常需要面对以下挑战: 测试脚本结构混乱,难以维护和复用。复杂交互场景(如滑动、拖拽)脚本难以编写和调试。跨平台测试需要解决设备兼容性和平台差异。 本文将结合…

MATLAB矩阵中元素的引用

建立矩阵后,我们在用矩阵元素的时候也会用到很多操作: 引用元素 分号前面的表示行,后面表示列 a ( m , n ) a(m,n) a(m,n)取出第 m m m行第 n n n列的元素 a ( [ m , n ] , e n d ) a([m,n],end) a([m,n],end)取出第 m m m行到第 n n n行最…

SpringBoot多环境+docker集成企业微信会话存档sdk

SpringBoot多环境docker集成企业微信会话存档sdk 文章来自于 https://developer.work.weixin.qq.com/community/article/detail?content_id16529801754907176021 SpringBoot多环境docker集成企业微信会话存档sdk 对于现在基本流行的springboot环境,官方文档真是比…

JavaScript:DOM节点操作

DOM节点操作 节点操作的概述如下: (1)创建节点:可以使用 DOM 提供的方法来创建新的节点,例如使用 createElement 方法创建元素节点,使用 createTextNode 方法创建文本节点等。 (2)添…

2、计算机网络七层封包和解包的过程

计算机网络osi七层模型 1、网络模型总体预览2、数据链路层4、传输层5.应用层 1、网络模型总体预览 图片均来源B站:网络安全收藏家,没有本人作图 2、数据链路层 案例描述:主机A发出一条信息,到路由器A,这里封装目标MAC…

附件的上传和回显

工作中的实战: 上传多个附件,supItemfileList存着多个附件的数据,如下图 根据你的业务场景不同,需要调试优化此代码 import React, { useMemo, useState } from reactimport { Upload, Form, Col, Row } from antdconst ShowA pr…