使用类和字典存储实例时单例不同的行为

问题描述 投票:0回答:1

为什么这两个基类会导致子对象具有不同的行为?

class Base:

    _instance: "Base" = None

    def __new__(cls) -> "Base":
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

class A(Base):
    def foo(self):
        return "foo"

class B(Base):
    def quz(self):
        return "quz"

a = A()
b = B()

print(id(a))
print(id(b))
140035075937792
140035075948400

另一方面

from typing import Dict

class Base:

    _instances: Dict[int, "Base"] = {} 

    def __new__(cls) -> "Base":
        if 0 not in cls._instances:
            cls._instances[0] = super().__new__(cls)
        return cls._instances[0]

class A(Base):
    def foo(self):
        return "foo"

class B(Base):
    def quz(self):
        return "quz"

a = A()
b = B()

print(id(a))
print(id(b))
140035075947296
140035075947296
python singleton
1个回答
0
投票

当执行

a = A()
时,会调用
__new__
方法,并以类
A
作为参数。这设置了类属性
A._instance
的值。同样,
b = B()
设置
B._instance
的值。

第一种情况,

Base._instance
A.instance
B._instance
的原始值为
None
,它是一个不可变对象,所以在
A
B
中改变这个值不会影响另外两门课。

在第二种情况下,

A._instance
B._instance
Base._instance
指向同一个字典。由于字典是一个可变对象,因此通过一个类修改该字典会影响所有三个类。

© www.soinside.com 2019 - 2024. All rights reserved.