首页 > 解决方案 > 在 python Singleton 设计模式中得到错误的输出

问题描述

我正在制作一个单例设计模式,一切都很顺利。

看下面的代码:

class Singleton():
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super().__new__(cls)
        return cls.instance

s1 = Singleton()
s2 = Singleton()

print(s1 is s2)
# True

但这不是单例,因为用户可以delattr(Singleton,'instance')在创建s1和之间s2使用这个简单的函数s1 is s2返回 False

所以我决定改为instance__instance停止用户使用delattr(Singleton,'instance')),但是当我这样做时,我在打印时得到 False s1 is s2 (我的新代码(__instance))

class Singleton():
    def __new__(cls):
        if not hasattr(cls, '__instance'):
            cls.__instance = super().__new__(cls)
        return cls.__instance

s1 = Singleton()
s2 = Singleton()

print(s1 is s2)
# False

但问题出在哪里?为什么当我更改instance结果时__instance我得到的是 False?

(我知道创建单例的其他方法我只是想知道我在课堂上的不同之处instance和时间,而不是我自己的私人)__instance__instance

标签: pythondesign-patternssingletonprivate-members

解决方案


Python 名称会破坏变量。它在类中称为“_Singleton__instance” __dict__。您可以改用该名称或使用异常处理程序进行分配。在这种情况下,python 会为您进行修改,它也适用于 Singleton 的子类。

class Singleton():
    def __new__(cls):
        # could do this ....
        #if not hasattr(cls, '_Singleton__instance'):
        #    cls.__instance = super().__new__(cls)
        #return cls.__instance
        try:
            return cls.__instance
        except AttributeError:
            cls.__instance = super().__new__(cls)
            return cls.__instance

s1 = Singleton()
s2 = Singleton()

print(s1 is s2)

当然它仍然很容易被击败

delattr(Singleton, "_Singleton__instance")
s3 = Singleton()
print(s1 is s3)

Python 是一种非常动态的语言,如果有人想伤害自己,那就试试吧!


推荐阅读