为什么一个base class单例还会多次调用构造函数?

Why does a base class singleton still call the constructor mulitple times?

我正在定义一个 Python 单例,如下所示:

class Database:
    initialized = False

    def __init__(self):
        self.id = random.randint(1,101)
        print("Generated an id of ", self.id)
        print("Loading database from file")

    _instance = None

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

从某种意义上说,这是有效的,即对 Database() 的每一次调用实际上都是 returns 一个且唯一的实例。但是,__init__() 方法 still 在每次调用时都会被调用。例如,

database = Database()

if __name__ == '__main__':
    d1 = Database()
    d2 = Database()

    print(d1.id, d2.id)
    print(d1 == d2)
    print(database == d1)

产生输出

Generated an id of  8
Loading database from file
Generated an id of  89
Loading database from file
Generated an id of  81
Loading database from file
81 81
True
True

这是为什么?我该怎么做才能避免多次调用初始化程序?

创建一个实例分为两个步骤:①通过调用cls.__new__()创建一个"blank"实例,然后②通过调用obj.__init__().

初始化这个空白实例

在你的例子中,创建你的 class 的新实例调用你的 __new__(),它总是 returns 相同的(不是那么空白的)实例,然后通过调用 [= =13=] 在其中(抱歉双关语)。

我不确定是否有办法避免调用 __init__(),我认为至少没有直接的方法。我会接受这一点,只保留一个空的 __init__(),调用时不会受到伤害。

或者,也许最好不要创建新的单例实例(由于您的特殊 __new__() 方法)。相反,只需使用 cls.singleton 来存储您的唯一实例(单例)或仅使用 class 本身作为单例并在 class 和静态方法中制作所有内容。我通常选择后一种选择。