装饰器方式
作为类装饰器,实现单例
import threading
def singleton(cls):
_instance_lock = threading.Lock()
_instance = {}
def _singleton(*args, **kwargs):
if cls not in _instance: # 没有实例要重新创建才加锁
with _instance_lock:
if cls not in _instance: # 确认加锁时没有新实例(加锁存在时间差)
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return _singleton
@singleton
class Mytest:
def __init__(self):
time.sleep(1)
改写new方式
可以被继承,子类也是单例
import threading
class Singleton:
_instance_lock = threading.Lock()
# _instance = None
# def __new__(cls, *args, **kwargs):
# if not cls._instance: # 没有实例要重新创建才加锁
# with cls._instance_lock:
# if not cls._instance: # 确认加锁时没有新实例(加锁存在时间差)
# cls._instance = object.__new__(cls)
# return cls._instance
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"): # 没有实例要重新创建才加锁
with Singleton._instance_lock:
if not hasattr(cls, "_instance"): # 确认加锁时没有新实例(加锁存在时间差)
Singleton._instance = object.__new__(Singleton)
return Singleton._instance
class TestSingleton(Singleton):
def __init__(self, *args, **kwargs):
super(TestSingleton, self).__init__(*args, **kwargs)
time.sleep(1)
改写type元类方式实现
import threading
class MetaSingleton(type):
_instance_lock = threading.Lock()
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances: # 没有实例要重新创建才加锁
with MetaSingleton._instance_lock:
if cls not in cls._instances: # 确认加锁时没有新实例(加锁存在时间差)
cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class TestMetaSingleton(metaclass=MetaSingleton):
def __init__(self, *args, **kwargs):
self.name = 'a'
time.sleep(1)
总结:元类(metaclass) 可以通过方法 metaclass 创造了类(class),而类(class)通过方法 new 创造了实例(instance)