单例模式
一. 单例模式四种方式
1. 文件导入
2. 基于类
无法支持多线程
import threading class Singleton(object): def __init__(self): pass @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance obj = Singleton.instance()
支持多线程
import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): time.sleep(1) @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance # 第一次调用 def task(arg): obj = Singleton.instance() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start() # 第二次调用 time.sleep(20) obj = Singleton.instance()
3. 使用__new__
无法支持多线程
class Singleton(object): Singleton._instance = None def __init__(self): pass def __new__(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls, *args, **kwargs) return Singleton._instance
支持多线程
class Singleton(object): _instance_lock = threading.Lock() def __init__(self): pass def __new__(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls, *args, **kwargs) return Singleton._instance
4. 基于metaclass
-------------------------------(一)------------------------------- # 创建对象 class SingletonType(type): def __call__(cls, *args, **kwargs): obj = super(SingletonType,cls).__call__(*args, **kwargs) #type类帮创建__new__和__init__并返回 return obj class Foo(metaclass=SingletonType): def __init__(self,name): self.name = name obj = Foo("alex") -------------------------------(二)------------------------------- import threading class SingletonType(type): _instance_lock = threading.Lock() def __call__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): with SingletonType._instance_lock: if not hasattr(cls, "_instance"): cls._instance = super(SingletonType,cls).__call__(*args, **kwargs) return cls._instance class Foo(metaclass=SingletonType): def __init__(self,name): self.name = name obj1 = Foo('name') obj2 = Foo('name') print(obj1,obj2)
对比:
# ######################## 基于 类方法实现 ######################### """ import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): time.sleep(1) @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance # 使用先说明,以后用单例模式,obj = Singleton.instance() # 示例: # obj1 = Singleton.instance() # obj2 = Singleton.instance() # print(obj1,obj2) # 错误示例 # obj1 = Singleton() # obj2 = Singleton() # print(obj1,obj2) """ # ######################### 基于__new__方式实现 ######################### """ import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): pass def __new__(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls, *args, **kwargs) return Singleton._instance # 使用先说明,以后用单例模式,obj = Singleton() # 示例 # obj1 = Singleton() # obj2 = Singleton() # print(obj1,obj2) """ # ######################### 基于metaclass方式实现 ################### """ import threading class SingletonType(type): _instance_lock = threading.Lock() def __call__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): with SingletonType._instance_lock: if not hasattr(cls, "_instance"): cls._instance = super(SingletonType,cls).__call__(*args, **kwargs) return cls._instance class Foo(metaclass=SingletonType): def __init__(self,name): self.name = name obj1 = Foo('name') obj2 = Foo('name') print(obj1,obj2) """ # PS: 为了保证线程安全在内部加入锁