除了琐碎的数据类型,python 不可变对象 ID 是否相同?

Apart from trivial data types, then are python immutable object ids the same?

对于不可变数据类型,Python不保证两个构造产生两个不同的对象;因此,1+1 is 2 可能会或可能不会 return True。当然,mutable 类型 do 会产生单独的对象:[] is [] 将始终 return False.

来自 https://docs.python.org/3/reference/datamodel.html#objects-values-and-types:

Types affect almost all aspects of object behavior. Even the importance of object identity is affected in some sense: for immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value, while for mutable objects this is not allowed. E.g., after a = 1; b = 1, a and b may or may not refer to the same object with the value one, depending on the implementation, but after c = []; d = [], c and d are guaranteed to refer to two different, unique, newly created empty lists. (Note that c = d = [] assigns the same object to both c and d.)

>>> "abc" is "abc"
True
>>> [] is []
False
>>> 1 + 1 is 2
True

现在,除了琐碎的类型 intfloatboolstring,我希望 tuplefrozenset表现出相同的行为。

但我没有发现他们这样做的情况:

>>> {1, 2} is {1, 2}
False
>>> (1, ) is (1, )
False

是否有任何实现为单独的不可变对象产生相同的 id?

这些对象的所有 is 相等性都是解释器技巧的结果(这不是语言规范 AFAIK 的一部分,而是 CPython 的结果)

例如(with int).

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.

所以应该可以更改 1 的值。我怀疑 Python 在这种情况下的行为未定义。 :-)

对于字符串,python 会 interningboolint (issubclass(bool, int)) 的子类,它解释了 bool 的共享 id。 AFAIK,浮动(除了 3.8 中的文字)永远不会 return True for is equality.


在 python3.8 中,(1,) is (1,)actually True,因为文字计算发生了变化。

>>> (1,) is (1,)
<stdin>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
True

连同 is 用于文字的警告。但是,分配变量和执行比较是错误的(如预期的那样)。

请注意 tuple() is tuple()frozenset() is frozenset() 都 return 正确。但是,它们的可变对象(listset)没有这个 属性.