为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 id([1][::-1]) ==id([1]) 返回 True 而 [1][::-1]

为什么 id([1][::-1]) ==id([1]) 返回 True 而 [1][::-1]

HUX布斯 2023-12-29 15:02:57
我知道is运算符比较id两者的值,而不是值,但为什么在返回时id([1][::-1])==id([1])返回?True[1][::-1] is [1]Falseid([1][::-1]) ==id([1]) #True[1][::-1] is [1] #Fasleid([1]) ==id([1][::-1])#Fasle[1] is [1][::-1]#False
查看完整描述

1 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

id([1][::-1]) ==id([1])beingTrue是 CPython 的一个怪癖,它使用一个空闲列表来将lists 实现为堆栈。第一个id([1][::-1])被完全评估,并且list它生成的内容在完成时被释放。当[1]为 new 分配空间时list,它会在同一地址处获得相同的内存,这(在 CPython 中)相当于它的id.

id仅当对象存在时才保证 s 是唯一的;list因为在创建新的之前原始的已经消失了list,所以如果它们id在稍微不同的时间点具有相同的 s ,则不会违反任何保证。

测试的顺序很重要,因为id它本身是从小对象分配器中最近释放的块集中拉出的。这里的顺序是:

  1. 原件[1]分配在地址A

  2. 的结果[::-1]分配在地址B

  3. 此后,[1]分配 A 立即返回到 的list空闲列表中

  4. id返回int描述地址 B

  5. B的结果[::-1]返回到空闲列表(在 A 之前)

  6. 第二个[1]是分配,获取 B,之前使用的内存[::-1]

  7. id被调用,准确地产生id与以前相同的结果(因为 new[1]被赋予了最近从产生的内存中释放的内存list [::-1]),因为两个lists 都使用地址 B

这实际上比需要的更复杂;id([1]) == id([1])最终也会得到相同的结果(它只会在空闲列表list上少留下一个 s list)。

当你以相反的方式做时,会发生这种情况:

  1. [1]分配在地址A

  2. id返回一个新的int描述地址A

  3. [1]被释放并且地址A返回到池中

  4. 分配下一个[1],获得 A,与第一个相同的内存[1]

  5. [::-1]应用于它,list从新鲜记忆 B 中获取新的;[1]然后被扔掉

  6. id[::-1]根据获取描述地址 B的结果进行调用int;地址 A 和 B 的sid不匹配

如果您创建并存储了这两个lists,然后将id仍然存在的 slist相互比较,它们将是唯一的,因为这些内存重用恶作剧将无法发生。


查看完整回答
反对 回复 2023-12-29
  • 1 回答
  • 0 关注
  • 108 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信