python 设计模式之单例模式

文章目录

  • 1. 简介
  • 2. 实现方式
    • 1. 使用模块
    • 2. 使用装饰器
    • 3. 使用类装饰器实现单例
    • 4. 使用new关键字
  • 3. 总结

1. 简介

单例模式是一种常用的设计模式,在某些场景下,我们需要一个类无论获取多少次类的对象,都仅仅提供一个具体的实例,用以节省创建类对象的开销和内存开销,比如配置文件类,工具类等仅需要1个实例,就可以在各处使用,单例模式就可以实现这样的效果。
在python中实现单例模式的方法有多种,我们介绍常见的四种方式:

  • 使用模块
  • 使用装饰器
  • 使用类
  • 基于__new__方法实现

2. 实现方式

1. 使用模块

Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。

我们在一个模块中定义我们所需要的函数和数据,在这个模块中初始化一下这个类,创建一个类对象,这个类对象就是一个单例对象。

class People():
	'''
	在这个类中可以定义我们所需要的方法和属性
	'''
	pass

people = People()

把上面的代码保存在python的一个模块(user.py)中,在需要使用的时候,直接导入这个模块中的people对象即可,如下:

from user import people

2. 使用装饰器

def Singleton(cls):
    _instance = {}
 
    def _singleton():
        if cls not in _instance:
            _instance[cls] = cls()
        return _instance[cls]

    return _singleton
 
 
@Singleton
class People(object): 
    def __init__(self):
        pass
 
 
people_1 = People()
people_2 = People()
print(id(people_1)==id(people_2))

输出结果如下:

True

在使用装饰器实现单例模式的例子中,使用_instance = {}来保存类对象,使用了不变的类地址作为键,实例作为值,每次创建实例的时候,首先查看该类是否存在实例,存在的话直接返回该类的实例即可,否则新建一个实例并存放在字典中。

3. 使用类装饰器实现单例

class Singleton(object):
    def __init__(self, cls):
        self._instance = {}
        self._cls = cls

    def __call__(self, *args, **kwargs):
        if self._cls not in self._instance:
            self._instance[self._cls] = self._cls()
        return self._instance[self._cls]


@Singleton
class People(object):
    def __init__(self):
        pass


people_1 = People()
people_2 = People()
print(id(people_1) == id(people_2))

输出结果如下:

True

4. 使用new关键字

class Singleton(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        pass


single_1 = Singleton()
single_2 = Singleton()
print(id(single_1) == id(single_2))

输出结果如下:

True

使用 类名() 创建对象时,Python 的解释器首先会调用__new__方法为对象分配空间。__new__ 是一个 由 object 基类提供的内置的静态方法,主要作用有两个:在内存中为对象分配空间;返回对象的引用。然后再调__init__()方法对实例进行初始化,通常是对该实例的属性进行初始化。

3. 总结

单例模式就是对一个类,只获取其唯一的类实例对象,持续复用,以达到节省内存、节省创建对象的开销。

你可能感兴趣的:(python,基础,单例模式,python,设计模式)