Python进阶之实现单例模式的常见方法

【一】单例模式介绍

【1】什么是单例模式

  • 一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式

【2】为什么要学单例模式

  • 当一个类的功能比较单一,只需要一个实例对象就可以完成需求时,就可以使用单例模式来节省内存资源

【3】如何实现一个单例

  • 在python中,我们可以使用多种方法来实现单例模式
    • 使用模块
    • 使用装饰器
    • 使用类(方法)
    • 基于__new__方法实现
    • 基于元类metaclass实现

【二】类属性

  • 使用类属性保存实例,通过类方法获取实例。
  • 在第一次调用get_instance方法时创建实例,并在后续调用中直接返回该实例
  • 类产生对象
# 创建一个普通的类
class Student(object):
    pass


# 实例化类得到对象,类只要加()实例化就会产生一个全新的对象
stu1 = Student()
stu2 = Student()
print(id(stu1))  # 1711911837680
print(id(stu2))  # 1711911837680
# 两个对象的id不同
  • 类属性包装成方法
class Student(object):
    _instance = None

    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = Student('ligo', 18)
        return cls._instance


stu1 = Student.get_instance()
stu2 = Student.get_instance()
print(id(stu1))  # 2387386923232
print(id(stu2))  # 2387386923232
# id 相同,是同一个实例

【三】装饰器

  • 使用装饰器将原来的类包装成一个新的类,通过闭包和字典保存实例。
  • 在每次实例化时,先检查字典中是否已经存在该类的实例,如果不存在才创建实例并返回
def outer(cls):
    instance = {}

    def inner(*args, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]

    return inner


@outer
class MyClass(object):
    pass


obj1 = MyClass()
obj2 = MyClass()

print(id(obj1))  # 2051247611504
print(id(obj2))  # 2051247611504

【四】元类

  • 定义一个元类,在元类的__call__方法中判断实例是否已存在,如果不存在则调用父类的__call__方法来创建并返回实例
class MyType(type):
    def __init__(cls, class_name, class_bases, class_dict):
        super(MyType, cls).__init__(class_name, class_bases, class_dict)
        cls.instance = None

    def __call__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super(MyType, cls).__call__(*args, **kwargs)
        return cls.instance


class MyClass(metaclass=MyType):
    pass


obj1 = MyClass()
obj2 = MyClass()

print(id(obj1))  # 2202077462144
print(id(obj2))  # 2202077462144
# id 相同,是同一个实例

【五】基于__new__方法

  • 在Python中,对象的实例化过程通常遵循以下步骤:
    • 首先执行类的__new__方法,如果未定义此方法,将默认调用父类的__new__方法来创建一个实例化对象,然后再执行__init__方法来对这个新创建的对象进行初始化
  • 利用实例化过程来实现单例模式:
    • 在类的__new__方法中判断是否已经存在实例,如果存在,则直接返回现有实例,否则创建一个新实例
    • 这样就能够确保只有一个实例存在,从而实现了单例模式的效果
class Student(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super().__new__(cls)
        return cls._instance


stu1 = Student()
stu2 = Student()
print(id(stu1))  # 1711911837680
print(id(stu2))  # 1711911837680
# id相同,是同一个实例
# 重写__new__方法,在实例化对象时判断类中是否已有实例,如果没有则调用父类的__new__方法来创建并返回

【六】基于模块

class Student:
    pass


instance = Student()
# 将实例化操作放在模块级别,通过导入该模块来获取实例。
# 由于Python模块在运行时只会被导入一次,因此保证了实例的单一性
posted @   Ligo6  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
点击右上角即可分享
微信分享提示