云计算百科
云计算领域专业知识百科平台

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

单件模式

在这里插入图片描述

初步示例

创建实例前先判断是否已创建,已有就直接返回,没有才创建 在这里插入图片描述 在这里插入图片描述

实现方式

在这里插入图片描述

类加载时创建(推荐)

在这里插入图片描述

# 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__方法

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

双重检查加锁

在这里插入图片描述

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()

使用类装饰器

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

使用元类

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

要点总结

在这里插入图片描述

赞(0)
未经允许不得转载:网硕互联帮助中心 » 基于Python学习《Head First设计模式》第五章 单件模式
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!