为什么这个单例 class 的实例化给出了不同的值

Why is the insantiation of this singleton class giving different values

为什么这两个语句给出不同的结果...

d1 = Database()
d2 = Database()
print(d1.id == d2.id)

完整代码如下:

import random

class Database:
    initialized = False

    def __init__(self):
        self.id = random.randint(1, 101)

    _instance = None

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



print(Database().id == Database().id)
# False

d1 = Database()
d2 = Database()
print(d1.id == d2.id)
# True
如果 returned 实例是正确的 class,

__new__() 总是调用 __init__()。这意味着,每个 Database() 调用仍在进行并将新的随机值设置为 id

这个id是你定义的一个实例变量,它不会真正影响id()的结果,这就是为什么如果你这样做

print(Database() is Database())

它将 return True 即使 id 检查 return 错误。实例是相同的,您只是更改了两者之间的 id 值,因此它们的计算结果为 False.

第二种情况,因为实例相同,所以在赋值d2时,它们都得到了__init__()生成的值。您可以通过在分配 d2 之前和之后添加 print(d1.id) 来确认这一点。

您需要使用 initialized 布尔值才能正确跳过 __init__()

中的代码
import random

class Database:
    initialized = False

    def __init__(self):
        if not self.initialized:
            self.id = random.randint(1, 101)
            self.initialized = True

    _instance = None

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

如果您想查看单例的其他实现,请查看 issue with singleton python call two times __init__ class 或完全避免单例的替代方法。