基于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

要点总结

相关推荐
财经资讯数据_灵砚智能几秒前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年6月15日
大数据·人工智能·python·ai·信息可视化·自然语言处理·灵砚智能
砍材农夫2 分钟前
python环境|conda安装和使用(1)
开发语言·后端·python·conda
私人珍藏库4 分钟前
[Android] FX Player-安卓全格式播放器-比MX播放器好用
android·学习·工具·软件·多功能
Upsy-Daisy4 分钟前
Hermes Agent 学习笔记 09:MCP 集成,让 Agent 连接外部工具生态
笔记·学习
Odoo老杨17 分钟前
如何直接在线定制修改 Odoo UI界面?
css·python·crm·odoo·erp·中小企业数字化
zhouhui00122 分钟前
订单状态的 if-else 地狱上线就崩——状态模式的工业级落地
设计模式
派大鑫wink41 分钟前
Java 高级编程技巧(生产级实用,覆盖性能、并发、设计、JVM、语法、避坑)
开发语言·python
子嘉1131 小时前
【无标题】
python
冷小鱼1 小时前
TensorFlow 2.21 进阶实战:从训练优化到生产部署的完整指南
人工智能·pytorch·python·tensorflow