【Python笔记-设计模式】单例模式

一、说明

单例 是一种创建型设计模式,能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。

(一) 解决问题

维护共享资源(数据库或文件)的访问权限,避免多个实例覆盖同一变量,引发程序崩溃。

(二) 使用场景

  • 数据库连接
  • 文件操作
  • 所有需要维护对象变量一致性的场景

二、结构

  1. 单例 (Singleton) 类声明了一个名为get­Instance获取实例的静态方法来返回其所属类的一个相同实例。单例的构造函数必须对客户端 (Client) 代码隐藏。 调用获取实例方法必须是获取单例对象的唯一方式。

三、伪代码

python 复制代码
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
单例模式
"""

import threading


class Singleton1:
    """
    方法1, 实现__new__方法
    并在将一个类的实例绑定到类变量_instance上,
    如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
    如果cls._instance不为None,直接返回cls._instance
    """
    _instance = None
    _lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        with cls._lock:
            if not cls._instance:
                cls._instance = super().__new__(cls)
        return cls._instance


class Singleton2(type):
    """
    方法2,实现metaclass,利用metaclass在实例化时已经创建好实例,
    从而实现单例模式,注意必须通过metaclass实现
    """
    _instances = {}
    _lock = threading.Lock()

    def __call__(cls, *args, **kwargs):
        with cls._lock:
            if cls not in cls._instances:
                cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]


def singleton(cls):
    """
    方法3,使用装饰器
    """
    _instance = None
    _lock = threading.Lock()

    def wrapper(*args, **kwargs):
        nonlocal _instance
        with _lock:
            if _instance is None:
                _instance = cls(*args, **kwargs)
        return _instance

    return wrapper


class MyClass:
    a = 1


class MyClass1(Singleton1):
    a = 1


class MyClass2(metaclass=Singleton2):
    a = 1


@singleton
class MyClass3:
    a = 1


if __name__ == '__main__':
    """
    非单例模式
    2 4787260528
    1 4787260480
    
    方法1, 实现__new__方法
    2 4787260336
    2 4787260336
    
    方法2, 实现metaclass
    3 4787260192
    3 4787260192
    
    方法3, 使用装饰器
    4 4787260144
    4 4787260144
    """
    print("非单例模式")
    s1 = MyClass()
    s2 = MyClass()
    s1.a = 2
    print(s1.a, id(s1))
    print(s2.a, id(s2))
    print()

    print("方法1, __new__方法实现")
    s1_1 = MyClass1()
    s1_2 = MyClass1()
    s1_1.a = 2
    print(s1_1.a, id(s1_1))
    print(s1_2.a, id(s1_2))
    print()

    print("方法2, metaclass实现")
    s2_1 = MyClass2()
    s2_2 = MyClass2()
    s2_1.a = 3
    print(s2_1.a, id(s2_1))
    print(s2_2.a, id(s2_2))
    print()

    print("方法3, 使用装饰器")
    s3_1 = MyClass3()
    s3_2 = MyClass3()
    s3_1.a = 4
    print(s3_1.a, id(s3_1))
    print(s3_2.a, id(s3_2))

四、优缺点

优点

  • 实例唯一:单例模式确保某个类只有一个实例,这有助于节省内存,因为只有一个对象实例在内存中。
  • 避免频繁创建和销毁对象:由于单例对象只创建一次,可以减少频繁的创建和销毁对象带来的性能开销。
  • 便于资源管理:单例模式可以确保某个资源或服务在整个应用程序中只有一个实例,方便对资源的统一管理和优化。
  • 提高性能和资源利用率:单例模式可以避免对资源的重复占用,从而提高性能和资源利用率。

缺点

  • 难以测试和调试:由于单例对象是全局唯一的,其行为可能与其他对象存在耦合,导致测试和调试困难。
  • 难以扩展:单例对象通常只有一个实例,如果需要扩展功能或增加复杂性,可能会面临较大的挑战。
  • 线程安全问题:在多线程环境下,如果没有正确地实现线程同步,可能会导致单例对象的实例化出现问题或产生竞态条件。
  • 过度使用可能会产生依赖和耦合:如果过度使用单例模式,可能会导致代码之间的耦合度过高,不利于代码的维护和重构。
相关推荐
花酒锄作田16 分钟前
[python]argparse 包在聊天机器人中的应用
python
NiceCloud喜云2 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
AI玫瑰助手3 小时前
Python函数:默认参数的定义与注意事项
开发语言·python·信息可视化
weixin_468466853 小时前
全局与局部注意力机制新手实战指南
人工智能·python·深度学习·算法·自然语言处理·transformer·注意力机制
小糖学代码3 小时前
LLM系列:环境搭建:5.Python-dotenv 环境变量管理
人工智能·python·深度学习·神经网络
智慧物业老杨4 小时前
智慧物业合同周期管理系统:从风险预警到智能交接的全流程数智化落地方案
java·人工智能·python
橙橙笔记4 小时前
Python的学习第一部分
python·学习
voidmort5 小时前
3. 微调(Fine-tuning)与强化学习(RL)的核心思想
python·深度学习·算法
biter down5 小时前
基于 Pywinauto 的 QQ 音乐 GUI 自动化测试实践
python
人道领域5 小时前
【LeetCode刷题日记】669.修剪二叉搜索树
开发语言·python·算法