1 回答
TA贡献1851条经验 获得超3个赞
id([1][::-1]) ==id([1])
beingTrue
是 CPython 的一个怪癖,它使用一个空闲列表来将list
s 实现为堆栈。第一个id([1][::-1])
被完全评估,并且list
它生成的内容在完成时被释放。当[1]
为 new 分配空间时list
,它会在同一地址处获得相同的内存,这(在 CPython 中)相当于它的id
.
id
仅当对象存在时才保证 s 是唯一的;list
因为在创建新的之前原始的已经消失了list
,所以如果它们id
在稍微不同的时间点具有相同的 s ,则不会违反任何保证。
测试的顺序很重要,因为id
它本身是从小对象分配器中最近释放的块集中拉出的。这里的顺序是:
原件
[1]
分配在地址A的结果
[::-1]
分配在地址B此后,
[1]
分配 A 立即返回到 的list
空闲列表中id
返回int
描述地址 BB的结果
[::-1]
返回到空闲列表(在 A 之前)第二个
[1]
是分配,获取 B,之前使用的内存[::-1]
id
被调用,准确地产生id
与以前相同的结果(因为 new[1]
被赋予了最近从产生的内存中释放的内存list
[::-1]
),因为两个list
s 都使用地址 B
这实际上比需要的更复杂;id([1]) == id([1])
最终也会得到相同的结果(它只会在空闲列表list
上少留下一个 s list
)。
当你以相反的方式做时,会发生这种情况:
[1]
分配在地址Aid
返回一个新的int
描述地址A[1]
被释放并且地址A返回到池中分配下一个
[1]
,获得 A,与第一个相同的内存[1]
[::-1]
应用于它,list
从新鲜记忆 B 中获取新的;[1]
然后被扔掉id
[::-1]
根据获取描述地址 B的结果进行调用int
;地址 A 和 B 的sid
不匹配
如果您创建并存储了这两个list
s,然后将id
仍然存在的 slist
相互比较,它们将是唯一的,因为这些内存重用恶作剧将无法发生。
添加回答
举报