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

要点总结

相关推荐
海海不掉头发3 分钟前
【神经网络基础】-学习探索篇章-基础篇
人工智能·神经网络·学习
for_ever_love__4 分钟前
Objective-C学习:UI的初步了解
学习·ui·objective-c
lifallen4 分钟前
Flink Agents:从 DataStream 到 Agent 算子的接入与装配
java·大数据·人工智能·python·语言模型·flink
weixin_4434785113 分钟前
Flutter第三方常用组件包学习之状态管理
javascript·学习·flutter
Engineer邓祥浩17 分钟前
JVM学习笔记(5) 第二部分 自动内存管理 第4章 虚拟机性能监控、故障处理工具
jvm·笔记·学习
做cv的小昊17 分钟前
【conda】打包已有conda环境并在其他服务器上搭建
运维·服务器·python·conda·运维开发·pip·开发
Hommy8820 分钟前
【开源剪映小助手-客户端】目录扫描功能
python·开源·aigc·剪映小助手
Pocker_Spades_A21 分钟前
Python快速入门专业版(五十六)——爬虫会话管理:Cookie与Session原理及实战(保持登录状态)
开发语言·爬虫·python
MwEUwQ3Gx22 分钟前
深入理解 Java Deque 的设计哲学
java·开发语言·python
MoRanzhi120325 分钟前
scikit-learn 决策树分类详解:从原理、可视化到剪枝实战掌握 DecisionTreeClassifier
python·决策树·机器学习·数学建模·分类·scikit-learn·剪枝