python singleton metaclass dict vs non dict

时间:2018-04-03 15:48:45

标签: python singleton

我试图扩展我的python知识。所以我刚写了我的第一个单例元类:

class Singleton(type):
    _instance = None    

    def __call__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__call__(*args, **kwargs)
        return cls._instance

我刚检查(反馈)好旧的stackoverflow。让我们看看其他人如何做到这一点'我找到了这个解决方案:

class Singleton(type):
    _instances = {}    

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

有人可以解释一下为什么(黑客)我们需要那本字典吗?

1 个答案:

答案 0 :(得分:3)

这是为了支持继承。使用您的解决方案,继承自使用Singleton元类构建的类不允许子类拥有自己的singelton。

class Singleton(type):
    _instance = None    

    def __call__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__call__(*args, **kwargs)
        return cls._instance

class FirstSingleton(metaclass=Singleton):
    pass

class SecondSingleton(FirstSingleton):
    pass

x = FirstSingleton()
y = SecondSingleton()

x is y # True

如您所见,调用FirstSingleton()SecondSingleton()都返回了相同的实例。

但是使用字典允许类及其子类具有不同的单例。

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class FirstSingleton(metaclass=Singleton):
    pass

class SecondSingleton(FirstSingleton):
    pass

x = FirstSingleton()
y = SecondSingleton()

x is y # False

类和子类都返回了自己的单例实例。