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
posted @ 2020-11-30 15:08  SR丶  阅读(174)  评论(0编辑  收藏  举报