单例模式python实现

单例模式的意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。【1】

1.最简单的单例模式。【2】

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

通过定义__new__()方法保证每次创建实例时都是同一个实例。

2.单例模式
单例模式的类应该提供一个接口让客户端获取唯一个实例。【1】
2.1懒汉式单例模式
只有需要时才去获取单例实例。

class Singleton(object):
    __instance = None
    def __init__(self):
        if not Singleton.__instance:
            print(" __init__ method called..")
        else:
            print("Instance alreadly created:", self.getInstance())
    @classmethod
    def getInstance(cls):   # 全局访问点
        if not cls.__instance:
            cls.__instance = Singleton()
        return  cls.__instance

根据【1】,应该定义一个Singleton类,其构造函数应该是protected修饰的,只公开getInstance()接口,并且其唯一的实例__instance是private的,应该由Singleton的子类来实例。但是python和c++、java等不同,并没有这些修饰符。因此实现方式有所不同。

这里的代码是想让客户端不是通过实例化获取单例实例,而是通过getInstance()获取实例。因为其是类方法,因此可以直接通过类去调用,从而获取唯一的实例。同时,只有我们去调用getInstance()才会获取,因此是懒汉式的。

2.2饿汉式单例模式
在调用getInstance()前实例已经存在。从懒汉式很容易修改成饿汉式的。

3.元类实现单例模式
在python中,类的定义由它的元类决定,因此可以通过自己定义元类来定制自己所需要的类。
用__call__()阻断__new__()和__init__()。
实例化一个类的时候先调用__call__(),然后再调用__new__()和__init__()。

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

class Logger(metaclass=MetaSingleton):
    pass

logger1 = Logger()
logger2 = Logger()
print(logger1,logger2)

这里只是用元类简单实现单例模式,并没有严格按照上面第二部分要求实现。
首先我们定义一个元类MetaSingleton,继承type类。然后重写了__call__()方法。
然后我们定义一个类Logger,指定其元类是MetaSingleton。就是说类Logger是元类MetaSingleton的实例。

logger1=Logger()简单地看是实例化对象。
深层地看,在python中()是调用的语法,为什么Logger()可以调用,实际上是它的类,即元类定义了
call()方法。而在我们定义的__call__()方法中调用了父类的__call__()完成操作,即调用了type类的__call__()方法,而type类的__call__()方法实际上调用了Logger类的__new__()和__init__()方法来实现实例化的。而我们的Logger类没有重写这两个方法,因此会调用其父类object的这两个类。

4.Monostate单例模式
一个类有且只有一个对象。通常让实例共享对象相同状态,但不限制实例个数。

class Borg:
    __shared_state = {"1":"2"}
    def __init__(self):
        self.x = 1
        self.__dict__ = self.__shared_state


b = Borg()
b1 = Borg()
b.x = 4

print("Borg object 'b': ", b)
print("Borg object 'b1': ", b1)
print("Object State 'b': ", b.__dict__)
print("Object State 'b1': ", b1.__dict__)

这里b和b1是不同的实例,但它们共享相同状态__shared_state。

参考:
【1】设计模式:可复用面向对象软件的基础
【2】python设计模式第二版

猜你喜欢

转载自blog.csdn.net/weixin_38249995/article/details/86551702