当前位置: 首页 > news >正文

python的两种单例模式

基于模块的单例模式

在 Python 中,模块是天然的单例模式。因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,会直接加载 .pyc 文件,而不会再次执行模块代码。因此,可以将相关的类和实例定义在一个模块中,通过导入模块来获取唯一的实例。

# singleton_module.py
class SingletonClass:
    def __init__(self):
        self.value = 0

    def increment(self):
        self.value += 1

# 创建唯一的实例
singleton_instance = SingletonClass()

然后在另一个文件中使用这个单例实例:

# main.py
from singleton_module import singleton_instance

# 第一次调用
print(singleton_instance.value)  # 输出 0
singleton_instance.increment()

# 再次调用
from singleton_module import singleton_instance
print(singleton_instance.value)  # 输出 1

在 singleton_module.py 中定义了一个 SingletonClass 类,并创建了该类的一个实例 singleton_instance
在 main.py 中,无论导入多少次 singleton_instance,获取的都是同一个实例,因此对实例的操作会保持状态

基于装饰器的单例模式

使用装饰器可以在不修改原类代码的情况下,将类转换为单例类。装饰器会维护一个字典,用于存储类和其对应的实例,当第一次调用被装饰的类创建实例时,会将该实例存储在字典中,后续再次调用时,直接从字典中获取已创建的实例。

# 入参是一个类,出参是一个函数
def singleton_decorator(cls):
    instances = {}

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

    return get_instance

@singleton_decorator
class MySingleton:
    def __init__(self):
        self.value = 0

    def increment(self):
        self.value += 1

# 创建实例
instance1 = MySingleton()
instance2 = MySingleton()

print(instance1 is instance2)  # 输出 True,表示两个实例是同一个对象
instance1.increment()
print(instance2.value)  # 输出 1

代码解释
singleton_decorator 是一个装饰器函数,它接受一个类作为参数,并返回一个 get_instance 函数
instances 是一个字典,用于存储类和其对应的实例

get_instance 函数会检查 instances 字典中是否已经存在该类的实例,如果不存在则创建一个新实例并存储在字典中,然后返回该实例。
MySingleton 类被 singleton_decorator 装饰
每次创建 MySingleton 类的实例时,实际上都会返回同一个实例

优缺点

基于模块的方式简单直接,适合简单场景
基于装饰器的方式更加灵活,可以应用于多个不同的类

相关文章:

  • 深度剖析 NVIDIA Isaac Sim:重塑机器人开发的创新引擎
  • 跟着 Lua 5.1 官方参考文档学习 Lua (1)
  • 力扣 最长递增子序列
  • 149,[4] BUUCTF WEB [GYCTF2020]FlaskApp(不会)
  • 再谈SpringCloud Gateway源码
  • 【算法进阶详解 第一节】树状数组
  • 人工智能在文化遗产保护中的创新:科技与文化的完美融合
  • Redis离线安装
  • springboot项目如何部署到tomcat中
  • 深度学习算法:开启智能时代的钥匙
  • 前端为什么要使用new Promise包裹一个函数
  • 联合概率:定义、公式和示例
  • CRISPR spacers数据库;CRT和PILER-CR用于MAGs的spacers搜索
  • 强化学习-策略梯度算法
  • 复旦:LLM知识问答任务性能预测
  • 【第13章:自监督学习与少样本学习—13.4 自监督学习与少样本学习的未来研究方向与挑战】
  • Spring Boot02(数据库、Redis)---java八股
  • 利用xtquant高效获取财务数据:量化分析的重要补充
  • Python 注解字典操作秘籍:从入门到精通
  • vue3.x的toRefs详细解读以及示例
  • 长期对组织隐瞒真实年龄,广元市城发集团原董事韩治成被双开
  • 数理+AI+工程,上海交大将开首届“笛卡尔班”招生约20名
  • 七大交响乐团在沪“神仙斗法”,时代交响奏出何等时代新声
  • 最快3天开通一条定制公交线路!上海推出服务平台更快响应市民需求
  • 巴基斯坦称约50名印度士兵在克什米尔实控线丧生
  • 商务部再回应中美经贸高层会谈:美方要拿出诚意、拿出行动