基于Python学习《Head First设计模式》第五章 单件模式

单件模式

初步示例

创建实例前先判断是否已创建,已有就直接返回,没有才创建

实现方式

类加载时创建(推荐)

python 复制代码
# singleton.py
class Singleton:
    def __init__(self):
        self.value = "实例数据"

_instance = Singleton()  # 模块加载时创建实例

def get_instance():
    return _instance

# 使用
from singleton import get_instance
obj1 = get_instance()
obj2 = get_instance()
print(obj1 is obj2)  # True

优点:简单、线程安全、符合Python风格。

缺点:实例在导入时立即创建(非懒加载)。

重写__new__方法

python 复制代码
class Singleton:
    _instance = None

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

    def __init__(self):
        self.value = "初始化数据"

# 使用
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2)  # True
双重检查加锁
python 复制代码
import threading

class Singleton:
    _instance = None
    _lock = threading.Lock()  # 类似 Java 的 synchronized 锁
    
    def __new__(cls):
        # 第一次检查(无锁)
        if not cls._instance:
            # 获取锁(类似 synchronized 块)
            with cls._lock:
                # 第二次检查(有锁)
                if not cls._instance:
                    print("创建新实例")
                    cls._instance = super().__new__(cls)
                    # 在这里进行初始化操作
                    cls._instance.value = "初始化数据"
        return cls._instance

    def get_value(self):
        return self.value

# 创建多个线程
threads = []
for i in range(5):
    t = threading.Thread(target=Singleton(), name=f"Thread-{i+1}")
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

使用类装饰器

python 复制代码
import functools

def singleton(cls):
    _instances = {}
    
    @functools.wraps
    def wrapper(*args, **kwargs):
        if cls not in _instances:
            _instances[cls] = cls(*args, **kwargs)
        return _instances[cls]
    return wrapper

@singleton
class MyClass:
    def __init__(self, name):
        self.name = name

# 使用
a = MyClass("Alice")
b = MyClass("Bob")
print(a.name, b.name)  # Alice Alice
print(a is b)  # True

使用元类

python 复制代码
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 Logger(metaclass=SingletonMeta):
    def __init__(self, log_file):
        self.log_file = log_file

# 使用
logger1 = Logger("app.log")
logger2 = Logger("new.log")
print(logger1.log_file)  # app.log
print(logger1 is logger2)  # True

要点总结

相关推荐
程序员小远7 小时前
软件测试之单元测试详解
自动化测试·软件测试·python·测试工具·职场和发展·单元测试·测试用例
心无旁骛~7 小时前
python多进程和多线程问题
开发语言·python
星云数灵7 小时前
使用Anaconda管理Python环境:安装与验证Pandas、NumPy、Matplotlib
开发语言·python·数据分析·pandas·教程·环境配置·anaconda
计算机毕设匠心工作室8 小时前
【python大数据毕设实战】青少年抑郁症风险数据分析可视化系统、Hadoop、计算机毕业设计、包括数据爬取、数据分析、数据可视化、机器学习
后端·python
计算机毕设小月哥8 小时前
【Hadoop+Spark+python毕设】智能制造生产效能分析与可视化系统、计算机毕业设计、包括数据爬取、Spark、数据分析、数据可视化、Hadoop
后端·python·mysql
STLearner9 小时前
AI论文速读 | U-Cast:学习高维时间序列预测的层次结构
大数据·论文阅读·人工智能·深度学习·学习·机器学习·数据挖掘
黑客思维者10 小时前
LLM底层原理学习笔记:Adam优化器为何能征服巨型模型成为深度学习的“速度与稳定之王”
笔记·深度学习·学习·llm·adam优化器
kk哥889910 小时前
Swift底层原理学习笔记
笔记·学习·swift
计算机毕设小月哥10 小时前
【Hadoop+Spark+python毕设】中风患者数据可视化分析系统、计算机毕业设计、包括数据爬取、Spark、数据分析、数据可视化、Hadoop
后端·python·mysql