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

要点总结

相关推荐
程序员的世界你不懂14 分钟前
Appium+python自动化(八)- 认识Appium- 下章
python·appium·自动化
恸流失44 分钟前
DJango项目
后端·python·django
Julyyyyyyyyyyy2 小时前
【软件测试】web自动化:Pycharm+Selenium+Firefox(一)
python·selenium·pycharm·自动化
季鸢2 小时前
Java设计模式之观察者模式详解
java·观察者模式·设计模式
萌新小码农‍3 小时前
Spring框架学习day7--SpringWeb学习(概念与搭建配置)
学习·spring·状态模式
蓝婷儿3 小时前
6个月Python学习计划 Day 15 - 函数式编程、高阶函数、生成器/迭代器
开发语言·python·学习
行云流水剑3 小时前
【学习记录】深入解析 AI 交互中的五大核心概念:Prompt、Agent、MCP、Function Calling 与 Tools
人工智能·学习·交互
love530love3 小时前
【笔记】在 MSYS2(MINGW64)中正确安装 Rust
运维·开发语言·人工智能·windows·笔记·python·rust
蔡蓝3 小时前
设计模式-迪米特法则
设计模式·log4j·迪米特法则
一弓虽3 小时前
zookeeper 学习
分布式·学习·zookeeper