首页 > 编程语言 >python进阶(29)单例模式

python进阶(29)单例模式

时间:2022-11-24 13:35:42浏览次数:42  
标签:__ .__ 进阶 python 模式 实例 单例 cls

初识单例模式

 

单例模式含义

单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。
 

实现单例模式思路:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
 

单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。
 

单例模式优点

  • 由于单例模式要求在全局内只有一个实例,因而可以节省比较多的内存空间
  • 全局只有一个接入点,可以更好地进行数据同步控制,避免多重占用
  • 单例可长驻内存,减少系统开销

 

单例模式缺点

  • 单例模式的扩展是比较困难的
  • 赋于了单例以太多的职责,某种程度上违反单一职责原则
  • 单例模式是并发协作软件模块中需要最先完成的,因而其不利于测试
  • 单例模式在某种情况下会导致“资源瓶颈”

 

单例模式应用

  • 生成全局唯一的序列号
  • 访问全局复用的唯一资源,如磁盘、总线等
  • 单个对象占用的资源过多,如数据库等
  • 系统全局统一管理,如Windows下的Task Manager
  • 网站计数器(同步控制)

 

Python实现单例模式

 

使用模块

其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

常见的场景即logging模块,写好一个日志类模块后,并实例化一个logger, 整个项目就调用这个logger

// logging_module.py
class LoggerMgr(object):
    def foo(self):
        pass
   
mylogger = LoggerMgr()

 

__new__方法实现

class Singleton:
    __instance = None
    __init_flag = True

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super().__new__(cls)
        return cls.__instance

    def __init__(self, name):
        if Singleton.__init_flag:
            print("进行初始化")
            self.name = name
            Singleton.__init_flag = False

 

使用装饰器来获取单例对象

def singleton(cls):
    __instance = {}
    def getinstance(*args, **kwargs):
        if cls not in __instance:
            __instance[cls] = cls(*args, **kwargs)
        return __instance[cls]
    return getinstance


@singleton
class MyClass:
    a = 1

我们定义了一个装饰器 singleton,它返回了一个内部函数 getinstance,该函数会判断某个类是否在字典 instances 中,如果不存在,则会将 cls 作为 keycls(*args, **kwargs) 作为 value 存到 instances 中,否则,直接返回 instances[cls]
 

使用metaclass元类创建单例

元类(metaclass)可以控制类的创建过程,它主要做三件事:

  1. 拦截类的创建
  2. 修改类的定义
  3. 返回修改后的类
class Singleton(type):
    __instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls.__instances:
            cls.__instances[cls] = super().__call__()
        return cls.__instances[cls]


class MyClass(metaclass=Singleton):
    def __init__(self):
        self.blog = "blog"

标签:__,.__,进阶,python,模式,实例,单例,cls
From: https://www.cnblogs.com/jiakecong/p/16908519.html

相关文章

  • 【python算法】24点
    defsolution(numbers):res=set()defpoint24(numbers):iflen(numbers)==1:ifabs(eval(numbers[0])-24)<1e-10:......
  • Python Charles抓包配置实现流程图解
    配置大佬的博客真的很详细很详细,我就不重复造轮子了,看这里补充解释在这一步疑问很多,大佬说的不是很详细,就由我来补充下吧~在PC端Charles这样点击:之后会这样提示:我们......
  • 网易Python后台开发面经
    社招。总共3轮技术面+1轮HR面,难度中等。问的问题基本都比较务实,纯技术和八股,没有算法。一面(40min)这一面比较水,主要是摸底。自我介绍。简历项目和个人工作介绍。djang......
  • Python 快速入门
    目录Python快速入门1环境配置1.1简介1.2Python安装1.3其余软件1.4编辑器的使用2基础语法2.1特点2.2代码块2.3注释3数据类型3.1变量类型3.2数据结构3.3运算......
  • 【GUI开发案例】用python爬百度搜索结果,并开发成exe桌面软件!
    一、背景介绍你好,我是@马哥python说,一名10年程序猿。1.1老版本之前我开发过一个百度搜索的python爬虫代码,具体如下:【python爬虫案例】用python爬取百度的搜索结果!......
  • python3_字符串操作
    Python字符串|菜鸟教程(runoob.com)Python字符串方法(w3school.com.cn)1、记录内置函数用法:ifFullVersion.endswith('NIO')#如果字符串以指定值结尾,则endswith......
  • 力扣81(java&python)-搜索旋转排序数组 II(中等)
    题目:已知存在一个按非降序排列的整数数组nums,数组中的值不必互不相同。在传递给函数之前,nums在预先未知的某个下标k(0<=k<nums.length)上进行了旋转,使数组变为[......
  • ValueError:only one element tensors can be converted to Python scalars解决办法
    问题描述深度学习初学者的我在使用pytorchdebug深度神经网络模型的时候,list,tensor,array之间的转化太复杂了,总是傻傻分不清。这次又遇到问题:ValueError:onlyoneelement......
  • python代码报错No module named numpy问题
    1一般在“控制面板+cmd”中安装​​numpy​​在​​命令行​​窗口中输入"pipinstallnumpy"此时安装的numpy并不在python的目录行中则会出现Nomodulenamednumpy报错,即......
  • Python基础之字符串
    一、认识字符串字符串是Python中最常⽤的数据类型。我们⼀般使⽤引号来创建字符串。创建字符串很简单,只要为变量分配⼀个值即可。1、字符串特征⼀对引号字符串name1='To......