Python 设计模式之路(五)——单例模式
本节内容
- 什么是单例模式
- 作用
- Python实现
- 多线程的思考
- 弊端
一、什么是单例模式
类仅产生一个实例,且提供了这个实例的全局访问,这种模式就称之为单例模式
二、作用
- 确保类的实例被创建一个
- 为对象提供了一个全局访问点,即对象可被访问
- 控制共享资源的并行访问,即:共享资源指一个实例,同时访问指多个实例引用
三、Python实现
1.__new__ 方法
class Signleton(object): def __new__(cls, *args, **kwargs): if not hasattr(cls,'_instance'): cls._instance = super().__new__(cls) return cls._instance if __name__ == '__main__': s = Signleton() s1 = Signleton() print(s,s1)
2.类方法
class Singleton: _instance = None def __init__(self): pass @classmethod def get_instance(cls): if not cls._instance: cls._instance = Singleton return cls._instance
3.静态方法
class A: pass class B: pass class InstanceFactory: _instances = {} @staticmethod def get_instance(cls): if cls not in InstanceFactory._instances: InstanceFactory._instances[cls] = cls() return InstanceFactory._instances[cls] a1 = InstanceFactory.get_instance(A) a2 = InstanceFactory.get_instance(A) b1 = InstanceFactory.get_instance(B) b2 = InstanceFactory.get_instance(B) print(a1,a2) print(b1,b2)
4.元类+__call__方法
# 5.元类控制 # 思路: 元类控制类对象的创建,__call__可以控制对象调用, 元类+__call__可以实现单例 class MetaType(type): _instances = {} #拦截对象的__new__,__init__方法 def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(MetaType, cls).__call__(*args, **kwargs) #type.__call__ return cls._instances[cls] class A(metaclass=MetaType): pass
四、多线程的思考
# 补充:多线程版本 from threading import Lock class Singleton(object): singleton_lock = Lock() def __new__(cls, *args, **kwargs): if not hasattr(cls,'_instance'): with Singleton.singleton_lock: if hasattr(cls,'_instance'): cls._instance = super().__new__(cls) return cls._instance
五、弊端
- 一个实例,有多个引用=> 实例的状态难以把控
- 提供全局访问入口=>其他类乱引用,紧耦合