为什么这个单例 class 的实例化给出了不同的值
Why is the insantiation of this singleton class giving different values
为什么这两个语句给出不同的结果...
print(Database().id == Database().id)
(给出 False)
- 但它以这种方式给出 True
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 或完全避免单例的替代方法。
为什么这两个语句给出不同的结果...
print(Database().id == Database().id)
(给出 False)- 但它以这种方式给出 True
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
__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 或完全避免单例的替代方法。