gpt4 book ai didi

python - 类对象是单例吗?

转载 作者:太空狗 更新时间:2023-10-29 17:48:03 26 4
gpt4 key购买 nike

如果我们有x = type(a)x == y , 是否一定意味着 x is y

这是一个反例,但它是作弊:

>>> class BrokenEq(type):
... def __eq__(cls, other):
... return True
...
>>> class A(metaclass=BrokenEq):
... pass
...
>>> a = A()
>>> x = type(a)
>>> x == A, x is A
(True, True)
>>> x == BrokenEq, x is BrokenEq
(True, False)

而且我无法创建这样的反例:

>>> A1 = type('A', (), {})
>>> A2 = type('A', (), {})
>>> a = A1()
>>> x = type(a)
>>> x == A1, x is A1
(True, True)
>>> x == A2, x is A2
(False, False)

为了澄清我的问题 - 在不覆盖相等性 运算符的情况下做一些疯狂的事情,一个类是否有可能存在于两个不同的内存位置,或者导入系统是否以某种方式阻止了这种情况?

如果是这样,我们如何证明这种行为 - 例如,用 reload 做奇怪的事情或 __import__

如果不是,是否由语言保证或在任何地方记录?


结语:

# thing.py
class A:
pass

最后,这就是为我澄清真实行为的原因(并且它支持 Blckknght 回答中的声明)

>>> import sys
>>> from thing import A
>>> a = A()
>>> isinstance(a, A), type(a) == A, type(a) is A
(True, True, True)
>>> del sys.modules['thing']
>>> from thing import A
>>> isinstance(a, A), type(a) == A, type(a) is A
(False, False, False)

因此,尽管使用 importlib.reload 的代码可能会破坏类标识的类型检查,它也会破坏 isinstance反正。

最佳答案

不,除了使用元类 __eq__ 方法之外,没有办法创建两个比较相等但不相同的类对象。

虽然这种行为并不是类所特有的。对于没有在其类中定义 __eq__ 方法的任何对象,这是默认行为。该行为继承自 object,它是所有其他(新式)类的基类。仅对于具有其他一些相等语义的内置类型(例如,比较其内容的容器类型)和定义自己的 __eq__ 运算符的自定义类,它才会被覆盖。

至于在不同的内存位置获取对同一类的两个不同引用,由于 Python 的对象语义,这实际上是不可能的。对象的内存位置它的标识(至少在 cpython 中)。另一个具有相同内容的类可以存在于其他地方,但就像在您的 A1A2 示例中一样,它会被所有 Python 逻辑视为不同的对象。

关于python - 类对象是单例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33924950/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com