zoukankan      html  css  js  c++  java
  • python单例模式

    单例模式

    简介

    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。 当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

    优点

    • 对唯一实例的受控访问
    • 单利相当于全局变量,但防止了命名空间被污染
    • 对唯一实例的受控访问 单利相当于全局变量,但防止了命名空间被污染 与单利模式功能相似的概念:全局变量、静态变量(方法)

    缺点

    • 虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
    • 使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类
    • 不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致单例类中出现悬浮引用。

    单利实现方式

    基于__new__实现

    • 实现__new__方法,然后将类的一个实例绑定到类变量_instance上
    • 如果cls._instance为None,则说明该类还没有被实例化过,new一个该类的实例,并返回
    • 如果cls._instance不为None,直接返回_instance
    class Singleton(object):
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, '_instance'):	# 判断是否有_instance属性
                cls._instance = super().__new__(cls, *args, **kwargs)
                return cls._instance
    
            return cls._instance
    
        name = 'SR'
    
    
    s1 = Singleton()
    s2 = Singleton()
    print(s1.name)  # SR
    print(s2.name)  # SR
    print(id(s1))  # 140368628557584
    print(id(s2))  # 140368628557584
    print(s1 == s2)  # True
    print(s1 is s2)  # True
    

    使用元类实现

    本质上是方法一的升级版,使用metaclass(元类)的python高级用法,具体代码如下

    """
    class Singleton中的__init__在Myclass声明的时候被执行Myclass=Singleton()
    Myclass()执行时,最先执行父类的__call__方法(object,Singleton都作为Myclass的父类,
    根据深度优先算法,会执行Singleton中的__call__(),Singleton中的__call__()写了单例模式)
    """
    class Singleton(type):
    
        def __init__(self, name, bases, dict):
            super(Singleton,self).__init__(name,bases, dict)
            self._instance = None
    
        def __call__(self, *args, **kwargs):
            if self._instance is None:
                self._instance = super(Singleton,self).__call__(*args, **kwargs)
            return self._instance
    
    class MyClass(object,metaclass=Singleton):
        a = 1
    
    one=MyClass()
    two=MyClass()
    print(id(one))  # 1553247294800
    print(id(two))  # 1553247294800
    print(one == two)   # True
    print(one is two)   # True
    

    装饰器

    def singleton(cls, *args, **kwargs):
        instances = {}
        
        def _singleton():
            if cls not in instances:
                instances[cls] = cls(*args, **kwargs)
            return instances[cls]
    
        return _singleton
    
    
    @singleton
    class MyClass3(object):
        a = 1
    
    
    one = MyClass3()
    two = MyClass3()
    
    print(id(one))  # 140383866774528
    print(id(two))  # 140383866774528
    print(one == two)  # True
    print(one is two)  # True
    

    基于new方法

    python的单例模式__new__()在__init__()之前被调用,用于生产实例对象。利用这个方法和类的属性的特点可以实现设计模式的单例模式。单例模式是指创建唯一对象,单例模式设计的类只能实例化一个对象。

    class Singleton(object):
        __instance=None
    
        def __init__(self):
            pass
        def __new__(cls, *args, **kwargs):
            if Singleton.__instance is None:
                Singleton.__instance=object.__new__(cls,*args, **kwargs)
            return Singleton.__instance
    
    one=Singleton()
    two=Singleton()
    print(id(one))  # 2488569943376
    print(id(two))  # 2488569943376
    print(one == two)   # True
    print(one is two)   # True
    
  • 相关阅读:
    转载1
    转载
    WampServer的研究日记一
    第一期 花式自适应网页哪家强? 就选你啦
    缓动函数requestAnimationFrame用法
    原生js canvas 碰撞游戏的开发笔记2
    非常便利的前端模板smarty js 的使用
    原生js canvas 碰撞游戏的开发笔记
    Sublime Text 的研究日记
    面向对象设计模式(目录)
  • 原文地址:https://www.cnblogs.com/SR-Program/p/14061438.html
Copyright © 2011-2022 走看看