专栏首页python3python设计模式之单例模式

python设计模式之单例模式

一.理解单例模式

单例模式是一种创建型设计模式,它确保一个类有且只有一个特定类型的对象,并提供全局访问点。其意图为:

  • 确保类有且只有一个对象被创建
  • 为对象提供一个访问点,使程序可以全局访问该对象
  • 控制共享资源的并行访问

简单理解:单例即为单个实例,也就是每次实例化创建对象时获得的都是同一个对象,当然同一个对象的属性都是相同的,方法也是相同的,地址也是相同的,这样给我们带来的好处就是可以避免消耗过多的内存或CPU资源,例如数据库类,我们希望每次都使用同一个数据库对象来对数据库进行操作,以维护数据的一致性。又如模块的导入,如果没有导入该模块,则导入该模块并实例化,如果已经导入,则返回该模块的对象

二.python实现单例模式

1.基于new方法实现的单例模式

class Singleton():
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,'instance'):
            cls.instance=super(Singleton,cls).__new__(cls)
        return cls.instance

a=Singleton()
b=Singleton()
print(a)#<__main__.Singleton object at 0x00000220866EF400>
print(b)#<__main__.Singleton object at 0x00000220866EF400>

new方法为python实例化创建对象自动执行的函数,通过重写这个函数,使之先判断该类中是否有instance属性(利用反射),若没有则为创建一个对象并为该属性赋值,最后返回instance中的对象。通过这种方式我们实现了每次创建实例返回的都是类中的instance的值。

2.懒汉式实例化

class Singleton():
    __instance=None
    def __init__(self):
        pass
    @classmethod
    def getInstance(cls):
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__instance

a=Singleton.getInstance()#<__main__.Singleton object at 0x000001C85C114B38>
b=Singleton.getInstance()#<__main__.Singleton object at 0x000001C85C114B38>
print(a)
print(b)

我觉得这种方式最好理解,感觉像是手动完成单例创建逻辑,但注意获得实例一定要调用Singleton.getInstance()方法,直接a=Singleton()相当于没用单例。

3.基于元类的单例实现

class MetaSingleton(type):
    __instance={}
    def __call__(self, *args, **kwargs):
        if self not in MetaSingleton.__instance:
            MetaSingleton.__instance[self] = super(MetaSingleton,self).__call__()
        return MetaSingleton.__instance[self]

class Singleton(metaclass=MetaSingleton):
    def __init__(self):
        pass

a=Singleton()#<__main__.Singleton object at 0x0000025103984CC0>
b=Singleton()#<__main__.Singleton object at 0x0000025103984CC0>
print(a)
print(b)

执行Singleton()之后,首先会调用MetaSingleton中的call函数,如果Singleton类没有在instance中,则为其创建一个实例,也就是正常调用type中的call函数,将返回的对象存在instance中,以该类名为键,对象为值,最后返回这个对象,若instance中有该类,那就直接返回存储的对象。

这种方式我觉得较好,不用为每个类单独创建单例模式,只需将元类重写即可

三.单例模式的缺点

  • 全局变量可能在某处被修改,但开发人员仍然认为他们没有发生变化
  • 会对同一个对象创建多个引用
  • 所有类都依赖同一个全局变量,那么他们则变的紧密耦合

四.Monostate单态模式

这种模式的理念为:实例化的对象是不同的,但是对象的状态,属性是相同的,也就是单态模式。

class Monostate():
    _shared_state={}
    def __init__(self):
        self.x=1
        self.__dict__=self._shared_state

a=Monostate()
b=Monostate()
b.x=5
print(a)#<__main__.Monostate object at 0x000001C267714B38>
print(b)#<__main__.Monostate object at 0x000001C267714B00>
print(a.x)#5
a.c=4
print(b.c)#4

这里的实现方式为利用类中的dict方法,我感觉是将_shared_state赋给dict后,每个对象的dict的地址都是相同的,所以对象的属性存储的位置都相同,那么一个对象的属性变化,其余的属性也会发生变化。


参考《python设计模式(第2版)》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python 随笔

    # -*- coding: cp936 -*- import os,sys,time,smtplib,poplib #python -m BaseHTT...

    py3study
  • python之路---03 整型 boo

          2.  .bit_length() 计算整数在内存中占⽤的⼆进制码的⻓度

    py3study
  • Python-语法模板大全(常用)

    字符串方法详见:https://www.cnblogs.com/haochen273/p/10244032.html#%E5%AD%97%E7%AC%A6%E4...

    py3study
  • 【教程】简单教程:用Python解决简单的水果分类问题

    在这篇文章中,我们将使用Python中最流行的机器学习工具scikit- learn,在Python中实现几种机器学习算法。使用简单的数据集来训练分类器区分不同...

    AiTechYun
  • 从7点到9点写的小程序(用了模块导入,python终端颜色显示,用了点局部和全局可变和不可变作用域,模块全是自定义)

    小小咸鱼YwY
  • java设计模式(四)--单例模式

     Singleton最熟悉不过了,下面学习单例模式。转载:http://zz563143188.iteye.com/blog/1847029 单例对象(Sin...

    Ryan-Miao
  • Swift基础语法(三)

    chineseScore和mathScore也是存储属性,用来记录该学生的语文分数和数学分数。

    拉维
  • 国内首家!主导Apache Hadoop新版本发布的,是腾讯云这位小哥哥

    腾讯开源
  • 「开源者访谈录」第 2 期:国内开源圈 PHP 第一程序员是怎么炼成的?

    大家好,这里是「开源者访谈录」,本节目将通过问答的方式,对一些优秀的开源项目作者进行专访,并撰写成文,推送到我们公众号与知乎专栏等渠道,与大家一起学习,共同见证...

    GitHubDaily
  • Linux基金会企业开源指南系列之二 -- 开始创建开源项目(上)

    本文拥有创作共用授权之相同方式共享授权4.0版国际许可协议(Creative Commons Attribution ShareAlike 4.0 Intern...

    开源社

扫码关注云+社区

领取腾讯云代金券