首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >设计模式 | Python单例模式

设计模式 | Python单例模式

作者头像
Michael阿明
发布2026-03-25 13:33:39
发布2026-03-25 13:33:39
440
举报

文章目录

一、单例模式解释

二、Python中的单例实现

三、单例模式的“翻车现场”

四、适用场景

一、单例模式解释

单例模式的核心思想:无论程序如何调用,类都只能存在一个实例,并且所有人都得共享这个实例 。

二、Python中的单例实现

  1. 最Pythonic的“懒汉”写法:模块就是单例 Python的模块天然就是单例的——因为模块在第一次导入时会被缓存,后续导入都是“共享”同一个实例。
代码语言:javascript
复制
# emperor.py
class Emperor:
    def __init__(self):
        self.gold = 1000000

emperor = Emperor()  # 模块加载时自动创建实例

其他文件直接导入这个模块即可:

代码语言:javascript
复制
from emperor import emperor
emperor.gold -= 1  # 对所有的导入都生效
  1. 进阶版:用__new__魔法控制实例化 如果你想玩点高级操作,可以通过重写__new__方法,手动控制实例的创建:
代码语言:javascript
复制
class Emperor:
    _instance = None  

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance.gold = 1000000  
        return cls._instance

# 测试一下
e1 = Emperor()
e2 = Emperor()
print(e1 is e2)  # 输出:True!e1和e2是 同一个 对象

实例化的时候,如果 cls._instance 不为 None 就直接返回已有的实例

这种方法更灵活,但要注意线程安全问题

  1. 终极奥义:元类(Metaclass)

Python默认使用内置的type作为元类来创建类。当定义一个类时,Python会通过type元类自动处理类的属性和方法。如果需要自定义类的创建逻辑(比如动态修改类属性、强制约束类结构、自动注册子类等),就可以通过自定义元类实现,通过重写__new____init__ or __call__方法来实现

代码语言:javascript
复制
class SingletonMeta(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class Emperor(metaclass=SingletonMeta):
    def __init__(self):
        self.gold = 1000000

# 无论怎么创建,都是同一个
e1 = Emperor()
e2 = Emperor()
e3 = Emperor()
e1.gold = 0
print(e2.gold)  # 输出:0 
print(e3.gold) # 输出:0 

这种方法优雅且通用

三、单例模式的“翻车现场”

虽然单例模式很香,但也要小心“踩坑”:

  1. 全局变量的诅咒:单例本质上是全局变量的变体,滥用会导致代码耦合度高,变成“牵一发动全身”的大泥球。
  2. 测试地狱:单例的实例会一直存活,导致单元测试难以隔离依赖
  3. 分布式系统的噩梦:如果单例依赖本地资源(如内存缓存),在分布式场景下不适宜使用

四、适用场景

单例模式的使用场景主要集中在需要确保全局唯一实例高效共享资源的场合

  1. 资源共享与性能优化 当多个模块需要共享同一资源时(如日志文件、应用配置、数据库连接池等),单例模式可避免重复创建实例导致的资源浪费或性能损耗。例如,日志文件操作或配置读取通常通过单例实现统一管理。
  2. 控制资源访问 对需要严格控制资源的场景(如线程池、数据库连接池),单例模式能集中管理资源分配,减少资源竞争或过度消耗。例如,线程池设计中通过单例确保线程的复用性和可控性。
  3. 频繁创建/销毁的对象 对于频繁实例化又销毁的对象(如网站计数器、临时缓存),单例模式可提升性能并减少内存开销。例如,网站计数器通过单例保持全局状态的一致性。
  4. 全局访问点 需要全局唯一访问入口的场景,单例模式提供统一的访问接口。例如,配置文件读取后通过单例存储在内存中,供其他模块调用。
  5. 多模块协作 多个模块需共享同一对象实例时(如多个模块共用同一个数据源连接对象),单例模式确保对象的唯一性和一致性。

总结来看,单例模式的核心价值在于减少资源消耗、确保全局唯一性,但需注意其潜在缺点(如全局状态滥用可能导致代码耦合度高)。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Michael阿明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、单例模式解释
  • 二、Python中的单例实现
  • 三、单例模式的“翻车现场”
  • 四、适用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档