首页 > 编程语言 >Python的四种单例模式实现方式

Python的四种单例模式实现方式

时间:2024-04-02 19:34:36浏览次数:28  
标签:__ Singleton Python self instance 单例 四种 cls

★ 单例模式基本介绍

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

★ 实现单例的几种方式:

  • 模块导入
  • 添加装饰器(类装饰器和函数装饰器)
  • 重写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
    

标签:__,Singleton,Python,self,instance,单例,四种,cls
From: https://www.cnblogs.com/cs-songbai/p/18111348

相关文章

  • 构造函数init到底是什么作用 是下面的方法都可以从init里面获取参数吗?(AI+Python)
    大家好,我是Python进阶者。一、前言前几天在Python白银交流群【无敌劈叉小狗】问了一个Python基础的问题,问题如下:问一下构造函数init到底是什么作用是下面的方法都可以从init里面获取参数吗?二、实现过程这里【黄志诚】分享了自己的一个经验:全局呀,相当于初始化一个参数,全局都......
  • Python零基础教学(数据类型)
    文章目录数据类型数字类型文字类型(字符串)数字和文字的区别文字相加文字乘法布尔类型(条件判断)布尔变量数据类型在python中,有很多类型。数据类型是用来区分不同的数据的,他们的操作也不同。数据类型:数字、文字、布尔······今天就想先讲这三个类型·,数字和......
  • Linux上使用python处理docx转pdf教程
      今天在使用flask将生成好的docx文档转化为pdf的过程中,遇到了一些问题,本来在windows上转化的好好的,但是到了Linux上却是直接报错显示ModuleNotFoundError:Nomodulenamed'win32com'。  很明显他说的是在Linux系统下并没有win32com这个模块,所以通过百度发现python使用pdf2......
  • Python中is和==的区别有多大,你知道吗?
    Python中有很多运算符,今天我们就来讲讲is和==两种运算符在应用上的本质区别是什么。在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不......
  • java,postgresql,python中各种数据类型的占位长度,取值范围
    Java数据类型Java中的数据类型分为两类:基本数据类型和引用数据类型。基本数据类型数据类型占位长度取值范围byte1字节-128127short2字节-3276832767int4字节-21474836482147483647long8字节-92233720368547758089223372036854775807float4字节1.4E-453.4028235E38double8字节4.......
  • python改变字幕时间线
    #处理小时,和分钟字母串defmyHandle(she):kaishi_shi=sheiflen(str(kaishi_shi))<2:kaishi_shi_str="0%s"%str(kaishi_shi)else:kaishi_shi_str=str(kaishi_shi)print(kaishi_shi_str)returnkaishi_shi_str#处理......
  • python改变文件修改时间
    代码:importosimporttime,datetimedefchange_file_time(file_path,new_timestamp):#使用stat函数获取文件的状态file_stat=os.stat(file_path)#更新文件的访问时间和修改时间os.utime(file_path,(file_stat.st_atime,new_timestamp))......
  • Python加载C语言动态库
    ★背景说明1.python是一门胶水语言,可以通过加载动态库的方式在一个项目中运行不同语言的程序2.通过动态库加载其他语言的方式可以解决多线程GIL使用C解释器无法并发运行的问题★在Linux中运行C代码:编辑C语言代码//hello.c//c代码作为启动文件必须加include<stdio......
  • python selenium 速查笔记
    1.安装与配置pipinstallselenium基本使用selenium都是为了动态加载网页内容用于爬虫,所以一般也会用到phantomjsmac下如果要配置phantomjs环境的话echo$PATHln-s<phantomjs地址><PATH中任一路径>至于chromeDriver,配置方法类似,下载地址:https://sites.google.com/a/chro......
  • python基础——基础代码每日复习
    '''字符串的格式化方法一,示例'''name="张三"money=102desc="今天收到{}的学费{}元"string=desc.format(name,money)print(string)#今天收到张三的学费102元'''字符串的格式化方法一,示例'''str='今天在{}......