我知道 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
(x
和 y
是可变对象),我们能保证改变 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 b
是 True
,因为今天的实现碰巧重用一个空的 frozenset。但是,例如,碰巧的是
>>> a = frozenset([3])
>>> b = frozenset([3])
>>> a is b
False
今天。它也可以明天返回 True
(尽管这不太可能 - 虽然空的 frozenset 是一种易于检测的特殊情况,但确保所有 frozenset 对象的唯一性代价高昂)。
关于python - "is"Python 运算符是否可以可靠地测试可变对象的引用相等性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63207389/