首页 > 编程语言 >Python设计模式详解之1 —— 单例模式

Python设计模式详解之1 —— 单例模式

时间:2024-11-19 09:18:53浏览次数:3  
标签:__ Python instances 实例 单例 ._ 设计模式 cls

单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。单例模式适用于需要确保全局唯一实例的场景,例如配置管理、日志记录器、数据库连接等。

1. 单例模式的特点

  • 全局唯一性:在整个应用程序的生命周期内,单例类只能有一个实例。
  • 全局访问:提供了一个全局访问点,任何地方都可以获取到该实例。
  • 延迟实例化:单例模式可以延迟实例化,即实例在第一次使用时才创建。

2. 实现单例模式的方法

在Python中,可以通过多种方式实现单例模式。以下是几种常见的方法:

方法一:使用类的静态实例
class Singleton:
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

# 测试
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2)  # 输出: True

解释:

  • 类变量 _instance 用于保存类的唯一实例。
  • __new__ 方法在实例创建时调用,确保实例只会被创建一次。
方法二:使用装饰器
def singleton(cls):
    instances = {}

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

    return get_instance

@singleton
class MyClass:
    pass

# 测试
obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)  # 输出: True

解释:

  • 装饰器 singleton 用字典存储类的实例,如果实例不存在,就创建一个新的实例。
方法三:使用模块

Python模块本身就是单例的。可以直接在模块中定义全局变量来实现单例模式:

# singleton_module.py
class Singleton:
    def __init__(self):
        self.value = 42

singleton_instance = Singleton()

解释:

  • 模块在首次导入时会被初始化并保持单例状态。

使用元类(metaclass)来实现单例模式是Python中特有且更高级的方式。元类是控制类创建行为的“类的类”,通过自定义元类,我们可以控制类的实例化过程来实现单例模式。

方法四:使用元类实现单例模式

使用元类实现单例模式的核心思想是在__call__方法中拦截类的实例化过程,从而确保类只有一个实例。

实现方法
class SingletonMeta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            # 创建一个新的实例,并将其存入_instances字典中
            cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

# 使用元类实现单例模式的类
class SingletonClass(metaclass=SingletonMeta):
    def __init__(self):
        print("Instance created")

# 测试
obj1 = SingletonClass()
obj2 = SingletonClass()
print(obj1 is obj2)  # 输出: True

解释

  • SingletonMeta继承自type,因此是一个元类。
  • __call__方法在类实例化时被调用。通过重写此方法,我们可以控制类实例的创建过程。
  • _instances是一个类变量,用于保存每个类的唯一实例。如果类实例不存在,则调用super().__call__()来创建一个新实例并存储在_instances中;如果已存在,直接返回存储的实例。

元类实现的优点

  • 灵活性:可以将元类应用于多个不同的类,从而减少重复代码。
  • 可扩展性:方便地在单例逻辑中添加额外功能,如线程安全控制。

3. 线程安全性改进

在多线程环境中,需要确保单例模式是线程安全的。可以使用线程锁来实现:

import threading

class SingletonMeta(type):
    _instances = {}
    _lock = threading.Lock()  # 锁对象用于同步

    def __call__(cls, *args, **kwargs):
        with cls._lock:  # 确保线程安全
            if cls not in cls._instances:
                cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class SingletonClass(metaclass=SingletonMeta):
    def __init__(self):
        print("Instance created")

# 测试
obj1 = SingletonClass()
obj2 = SingletonClass()
print(obj1 is obj2)  # 输出: True

4. 应用场景

  • 日志系统:日志记录器在整个应用程序中应当只有一个实例来防止资源竞争。
  • 配置管理:使用单例模式来加载和管理配置文件以确保一致性。
  • 资源共享:在涉及共享资源如数据库连接池时,单例模式可以有效管理连接实例。

5. 注意事项

  • 单例模式的实现要保证线程安全,特别是在多线程应用中。
  • 过度使用单例模式会导致代码耦合度高,因此应谨慎使用,确保符合设计需求。

单例模式虽然简单,但其全局状态可能带来潜在的问题,例如难以进行单元测试或状态管理不清晰。在使用时要权衡利弊。

标签:__,Python,instances,实例,单例,._,设计模式,cls
From: https://blog.csdn.net/huaanxiang/article/details/143843320

相关文章

  • Python设计模式详解之2 —— 工厂模式
    工厂模式(FactoryPattern)是一种创建型设计模式,旨在定义一个用于创建对象的接口,但由子类决定实例化哪个类。工厂模式可以帮助我们将对象的创建与其使用分离,增强代码的可扩展性和维护性。工厂模式的分类简单工厂模式(SimpleFactoryPattern)工厂方法模式(FactoryMethodPatte......
  • (免费源码)计算机毕业设计必看必学 原创定制程序 java、PHP、python、小程序、文案全套
    摘 要为了方便用户快速定位自己感兴趣的国内热门旅游景点信息,国内热门景点推荐系统应运而生。本系统的前端界面主要实现页面的美观和动态效果使之符合广大群众的审美观,后台主要使用的技术主要有Java编程语言,SSM框架,MySQL数据库的旅游推荐系统解决了传统旅游推荐方式中数据......
  • Python设计模式详解之3 —— 抽象工厂模式
    抽象工厂模式也是一种创建型设计模式,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。它特别适合在需要创建多个相关对象且这些对象在逻辑上属于一个“产品族”时使用。结构:抽象产品:定义了产品家族中每个产品的接口。具体产品:实现抽象产品接口......
  • (分享源码)计算机毕业设计必看必学 上万套实战教程手把手教学JAVA、PHP,node.js,C++、pyth
     摘 要21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认知向理性认知提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到准确、快速、完善,并能提高工作管理效率,促进其发展。论文主要是对医疗门诊管理......
  • (分享源码)计算机毕业设计必看必学 上万套实战教程手把手教学JAVA、PHP,node.js,C++、pyth
     摘 要随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,校园跳蚤市场管理系统被用户普遍使用,为方便用户能够可以随时进行校园跳蚤市场管理系统的数据信息管理,特开发了基于spri......
  • AI豆包-Python SDK接入流程(完整代码)
    在当今的软件开发领域,与各类人工智能模型进行交互以获取智能回复是一项常见且重要的任务。本文将聚焦于一个名为 doubao 的Python函数,详细剖析它是如何与特定的人工智能模型进行连接并获取回复的,为大家揭示其背后的技术细节。Python实现AI豆包智能回复微信运行结果:第......
  • Python课程设计之俄罗斯方块
    资源结构源码文件(可通过pycharm直接运行)tk.exe(打包好的程序,可双击运行)实验报告(最重要的一部分,本实验报告完全基于学校要求认真编写的,并获得了优秀的评分)程序运行视图程序启动步骤使用pycharm打开tk.py文件设计拦截器为python3.10点击启动按钮启动可执行程序-tk.e......
  • Java设计模式 —— Java七大设计原则详解
    文章目录前言一、单一职责原则1、概述2、案例演示二、接口隔离原则1、概述2、案例演示三、依赖倒转原则1、概述2、案例演示四、里氏替换原则1、概述2、案例演示五、开闭原则1、概述2、案例演示六、迪米特法则1、概述2、案例演示七、合成/聚合复用原则1、概述......
  • python毕设车位预约小程序程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于车位预约小程序的研究,现有研究多集中在大型停车场管理系统或者通用的预约平台方面,专门针对以Python实现的车位预约小程序的研究较......
  • 用pip进行安装时提示“Package requires a different Python: 3.8.10 not in ‘>=3.9‘
    用pip进行安装时提示“PackagerequiresadifferentPython:3.8.10notin'>=3.9'“报错“Package'dpgen-0.12.2.dev1-g6943db5'requiresadifferentPython:3.8.10notin'>=3.9'”修改pip关联的python版本way1修改pip关联的python版本way2报错“Package‘......