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
五、弊端
- 一个实例,有多个引用=> 实例的状态难以把控
- 提供全局访问入口=>其他类乱引用,紧耦合
浙公网安备 33010602011771号