单例模式确保一个类只有一个实例,并提供全局访问点。在Python中 ,装饰器是实现这一设计模式的优雅方式。本章将探索单例装饰器的三种不同实现途径。
7.1 实现Singleton模式
最基本的形式是通过装饰器来确保类的实例化仅发生一次。
def singleton(cls):
_instance = {}
def get_instance(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return get_instance
@singleton
class MySingleton:
def __init__(self, value=None):
self.value = value or "default"
s1 = MySingleton("instance one")
s2 = MySingleton("instance two")
print(s1.value) # 输出: instance one
print(s2.value) # 输出: instance one ,证明s1和s2是同一个实例7.2 类装饰器实现单例
类装饰器提供了一种面向对象的方式来实现单例模式,可以封装更多的逻辑。
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 SingletonClass(metaclass=SingletonMeta):
def __init__(self, value=None):
self.value = value or "singleton class instance"
obj1 = SingletonClass("first init")
obj2 = SingletonClass("second init")
print(obj1.value) # 输出: first init
print(obj2.value) # 同样输出: first init7.3 线程安全的单例模式
在多线程环境下,上述实现可能面临竞态条件。使用threading.Lock确保线程安全。
import threading
def thread_safe_singleton(cls):
_instance = {}
_lock = threading.Lock()
def get_instance(*args, **kwargs):
with _lock:
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return get_instance
@thread_safe_singleton
class ThreadSafeSingleton:
def __init__(self, value=None):
self.value = value or "thread safe singleton"
# 在多线程环境中测试ThreadSafeSingleton
# (此处省略多线程测试代码 ,但在实际应用中需确保测试环境支持并发验证)
通过这些方法 ,我们不仅实现了单例模式的基本逻辑,还考虑到了线程安全,确保了在并发环境下的正确性。这些实现展示了装饰器在设计模式应用中的强大与灵活性。