实现单例的几种成熟设计模式

2022-03-18  本文已影响0人  托贝多尔

装饰器方式

作为类装饰器,实现单例

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)

上一篇 下一篇

猜你喜欢

热点阅读