请注意,这个问题可能(是?)特定于 CPython。
假设您有一些列表,并检查列表的副本以确保彼此的身份:
>>> a=list(range(10))
>>> b,c=a[:],a[:]
>>> b is c
False
>>> id(b), id(c)
(3157888272304, 3157888272256)
那里没有剧烈震动。但如果我们以更短暂的方式做到这一点,一开始事情可能看起来有点奇怪:
>>> a[:] is a[:]
False # <- two ephemeral copies not the same object (duh)
>>> id(a[:]),id(a[:])
(3157888272544, 3157888272544) # <- but two other ephemerals share the same id..? hmm....
...直到我们认识到这里可能发生了什么。我还没有通过查看 CPython 实现来确认这一点(老实说,我几乎看不懂 c++,所以这会浪费时间),但至少看起来很明显,即使两个对象具有相同的 id,CPython 也是聪明的足以知道它们不是同一个对象。
假设这是正确的,我的问题是:CPython 使用什么标准来确定两个临时对象是否不是同一个对象,因为它们具有相同的 id(大概是出于效率原因 - 见下文)?是否可能会查看它被标记为垃圾收集的时间?创建时间?还是别的什么...?
我对“为什么”它们具有相同 id 的理论是,CPython 可能知道列表的临时副本已经创建并正在等待垃圾收集,并且它只是有效地重用相同的内存位置。如果答案也能澄清/确认这一点,那就太好了。
问题是,当您执行
a[:] is a[:]
时,两个对象
not位于同一地址 - 为了使恒等运算符
is
比较两个对象,两个操作数都必须存在 - 因此,仍然存在对当 is
的本机代码实际运行时左侧的对象。另一方面,当您执行
id(a[:]),id(a[:])
时,一旦
id
函数调用完成,第一次调用时括号内的对象将没有任何引用,并被销毁,释放内存块以供使用第二个a[:]
。