单件模式
初步示例
创建实例前先判断是否已创建,已有就直接返回,没有才创建
实现方式
类加载时创建(推荐)
# 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