python - "is"Python 运算符是否可以可靠地测试可变对象的引用相等性?

标签 python reference identity equality mutable

我知道 Python 中的 is 运算符对不可变对象(immutable对象)(如整数和字符串)有意想不到的行为。参见 "is" operator behaves unexpectedly with integers

>>> a = 0
>>> b = 0
>>> a is b
True        # Unexpected, we assigned b independently from a

当谈到可变对象时,我们是否保证预期(如代码中所写)引用两个不同对象(具有相等值)的两个变量不会在内部绑定(bind)到相同对象目的 ? (除非我们改变两个变量之一,否则引用当然会有所不同。)

>>> a = [0]
>>> b = [0]
>>> a is b
# Is False guaranteed ?

换句话说,如果某处 x is y 返回 True(xy 是可变对象),我们能保证改变 x 也会改变 y 吗?

最佳答案

只要您认为某些"is"行为是“意外”的,您的心智模型就与现实不符;-)

您的问题真的是关于 Python 何时保证创建新对象。而当它没有时。对于可变对象,是的,产生可变对象的构造函数(包括文字)总是创建一个新对象。这就是为什么:

>>> a = [0]
>>> b = [0]
>>> a is b

总是False。 Python 本可以 说过 [0] 的每个实例是否创建一个新对象是未定义的,但它没有:它保证每个实例总是创建一个新对象。 行为是它的结果,而不是它的驱动因素。

同样,

>>> a = set()
>>> b = set()
>>> a is b
False

也有保证。因为 set() 返回一个可变对象,所以它始终保证创建一个新的此类对象。

但对于不可变对象(immutable对象),它未定义。例如,未定义的结果:

>>> a = frozenset()
>>> b = frozenset()
>>> a is b

frozenset() - 与整数文字一样 - 返回一个不可变对象(immutable对象),是否返回一个新对象或重用现有对象取决于实现。在这个具体的例子中,a is bTrue,因为今天的实现碰巧重用一个空的 frozenset。但是,例如,碰巧的是

>>> a = frozenset([3])
>>> b = frozenset([3])
>>> a is b
False

今天。它也可以明天返回 True(尽管这不太可能 - 虽然空的 frozenset 是一种易于检测的特殊情况,但确保所有 frozenset 对象的唯一性代价高昂)。

关于python - "is"Python 运算符是否可以可靠地测试可变对象的引用相等性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63207389/

相关文章:

c++ - 没有匹配函数来调用 C++

java - 使用@Reference获取服务导致maven构建警告

Python:对象身份问题?

java - 设计 XACML API

python - 从 python 到 aplay

python - 在 python 中更新字典的最快方法

C++ 基础 vector 指派生 vector

java - id key 的自定义包装

python - 当矩形与另一个矩形重叠时,OpenCV 连接轮廓

python - 如何通过许多不同的 URL 获取唯一值