1. 单例模式

1.1 简介

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

1.2 单例模式优点:

1.节约内存,因为不管实例化多少个 对象都实际指向一个内存地址;
2.多个地方创建的实例他们的属性互动,如下例子:我们只给实例化对象t1添加了一个name属性,而t2和t3都拥有了这个属性,这就给我们节约了很多的时间;

2. 单例模式代码实现

2.1 实现单例模式第一种方法:

实例化一个的对象,要用时直接import导如这个对象,而不是再实例化一个,这样就做到了单例模式了,每次都用的是同一个对象,此处就不举例了

2.2 实现单例模式第二种方法:

我们知道,当我们实例化一个对象时,是先执行了类的__new__方法(我们没写时,默认调用object.new),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式

class User(object):
    def __init__(self):
        print("__init__ 方法执行")

    def __new__(cls, *args, **kwargs):
        print("__new__ 方法执行")
        cls.obj = object.__new__(cls)
        return cls.obj


User()
E:\pythonProject\venv\Scripts\python.exe E:/pythonProject/csdn_project/002.py
__new__ 方法执行
__init__ 方法执行

Process finished with exit code 0

从以上结果中我们看到,使用类创建对象时,先自动执行了new方法创建对象,然后返回给init进行初始化操作;


class User(object):
    instance = None

    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = object.__new__(cls)
            return cls.instance
        else:
            return cls.instance


t1 = User()
t2 = User()
t3 = User()
t4 = User()

print(t1)
print(t2)
print(t3)
print(t4)
E:\pythonProject\venv\Scripts\python.exe E:/pythonProject/csdn_project/003.py
<__main__.User object at 0x037D9088>
<__main__.User object at 0x037D9088>
<__main__.User object at 0x037D9088>
<__main__.User object at 0x037D9088>

Process finished with exit code 0

以上,通过new方法内判断是否创建过对象,来实现单例模式,我们实例化三个对象t1,t2,t3三个对象内存地址都是一样的,这就说明他们是同一个对象。

2.3 单例模式的第三种方法

通过装饰器实现单例模式:
任意一个类使用了该装饰器就会变成一个单例模式的类;


def single_class(cls):
    instance = {}

    def single(*arge, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*arge, **kwargs)
            return instance[cls]
        else:
            return instance[cls]
    return single


@single_class
class A():
    pass

t1 = A()
t2 = A()
print(t1)
print(t2)
E:\pythonProject\venv\Scripts\python.exe E:/pythonProject/csdn_project/004.py
<__main__.A object at 0x036CBF40>
<__main__.A object at 0x036CBF40>

Process finished with exit code 0

以上,我们写了一个装饰器,该装饰器将所有的对象都存储到字典里,如果之前创建过的对象就直接返回,如果没有创建过的对象那就new一个,同一个类我们实例化了t1和t2,但是他们的内存地址都是同一个,说明我们已经实现了单例模式的类装饰器;