• 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版)》

  • 相关阅读:
    关于同余最短路
    【水】关于 __attribute__
    题解【AtCoder
    一些简单图论问题
    浅谈简单动态规划
    关于博客园主题(美化博客园)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第47章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第46章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第45章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第44章 读书笔记(待更新)
  • 原文地址:https://www.cnblogs.com/sfencs-hcy/p/10022283.html
Copyright © 2020-2023  润新知