Python的四种单例模式实现方式
  VlRy1zDaWnkA 2024年04月02日 44 0

★ 单例模式基本介绍

单例模式是一种设计模式,用于确保一个类只有一个实例,并提供全局访问点以获取该实例。它是一种创建型模式,通常用于需要严格控制某个类的实例数量的情况。单例模式确保一个类在整个应用程序生命周期中只有一个实例,因此可以节省系统资源,同时提供了一个集中的访问点,以便在需要时获取该实例。

★ 实现单例的几种方式:

  • 模块导入
  • 添加装饰器(类装饰器和函数装饰器)
  • 重写new方法
  • 元类继承

★ 方式一: 模块导入

  • 文件结构
    单例
    ├───file1.py
    ├───file2.py
    ├───readme
    ├───单例实现1_模块导入.py
    └───模块导入实现单例测试.py
    
  • 单例实现1_模块导入.py
    """
    模块导入实现单例模式步骤:
    1. 在模块中定义类
    2. 实例化类并返回
    3. 在其他文件中导入实例对象使用, 每个文件导入的对象实际是同一个
    """
    
    
    class Singleton:
        def __init__(self, name):
            self.name = name
    
        def do_something(self):
            pass
    
    
    singleton = Singleton('模块单例')
    
    # 在其他py文件中
    # from my_singleton import singleton
    
  • file1.py
    from 单例实现1_模块导入 import singleton
    
    print(singleton)
    
  • file2.py
    from 单例实现1_模块导入 import singleton
    
    print(singleton)
    
  • 模块导入实现单例测试.py
    import file1
    import file2
    
    print(file1.singleton is file2.singleton)
    
  • 执行结果
    <单例实现1_模块导入.Singleton object at 0x0000021B2B81F400>
    <单例实现1_模块导入.Singleton object at 0x0000021B2B81F400>
    True
    

★ 方式二: 装饰器

  • 单例实现2_装饰器.py
    # -------------------函数装饰器---------------------------
    def Singleton1(cls):
        instance = {}
    
        def _singleton_wrapper(*args, **kargs):
            if cls not in instance:
                instance[cls] = cls(*args, **kargs)
            return instance[cls]
    
        return _singleton_wrapper
    
    
    # -------------------类装饰器---------------------------
    class Singleton2:
    
        def __init__(self, cls):
            self.cls = cls
            self._instance = None
    
        def __call__(self, *args, **kwargs):
            if not self._instance:
                self._instance = self.cls(*args, **kwargs)
            return self._instance
    
    
    # SingletonTest = Singleton1(SingletonTest) =_singleton_wrapper
    # SingletonTest = Singleton2(SingletonTest) = Singleton2实例对象
    @Singleton1
    class SingletonTest(object):
        def __init__(self, name):
            print(">>> 初始化 <<<")
            self.name = name
    
    
    s1 = SingletonTest('s1')
    s2 = SingletonTest('s2')
    print(s1, s2)
    print(s1 is s2)
    
    
    
  • 执行结果
    >>> 初始化 <<<
    <__main__.SingletonTest object at 0x000001E6A2FF73D0> <__main__.SingletonTest object at 0x000001E6A2FF73D0>
    True
    

★ 方式三: 重写new方法

  • 单例实现3_重写new方法.py
    class Singleton(object):
    
        def __new__(cls, *args, **kwargs):
            if not hasattr(Singleton, "_instance"):
                Singleton._init_flag = True
                Singleton._instance = super().__new__(cls)
            return Singleton._instance
    
        def __init__(self, name):
            if not hasattr(Singleton, "_init"):
                Singleton._init = True
                print(">>> 初始化 <<<")
                self.name = name
    
    
    s1 = Singleton('s1')
    s2 = Singleton('s2')
    print(s1, s2)
    print(s1 is s2)
    
  • 执行结果
    >>> 初始化 <<<
    <__main__.Singleton object at 0x0000016663140760> <__main__.Singleton object at 0x0000016663140760>
    True
    

★ 方式四: 元类继承

  • 单例实现4_元类继承.py
    class Singleton(type):
    
        def __call__(cls, *args, **kwargs):
            if not hasattr(Singleton, "_instance"):
                # cls 是 Singleton 创建的类
                Singleton._instance = cls.__new__(cls, *args, **kwargs)
                cls.__init__(Singleton._instance, *args, **kwargs)
            return Singleton._instance
    
    
    class SingletonTest(metaclass=Singleton):
        pass
    
    
    class A(SingletonTest):
        def __init__(self, name):
            print(">>> 初始化 <<<")
            self.name = name
    
    
    s1 = A('s1')
    s2 = A('s2')
    print(s1, s2)
    print(s1 is s2)
    
  • 执行结果
    >>> 初始化 <<<
    <__main__.A object at 0x000001687C79D5E0> <__main__.A object at 0x000001687C79D5E0>
    True
    
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年04月02日 0

暂无评论

推荐阅读
  KmYlqcgEuC3l   4天前   11   0   0 Python
VlRy1zDaWnkA
作者其他文章 更多