1 回答
TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超3個(gè)贊
id([1][::-1]) ==id([1])beingTrue是 CPython 的一個(gè)怪癖,它使用一個(gè)空閑列表來將lists 實(shí)現(xiàn)為堆棧。第一個(gè)id([1][::-1])被完全評(píng)估,并且list它生成的內(nèi)容在完成時(shí)被釋放。當(dāng)[1]為 new 分配空間時(shí)list,它會(huì)在同一地址處獲得相同的內(nèi)存,這(在 CPython 中)相當(dāng)于它的id.
id僅當(dāng)對(duì)象存在時(shí)才保證 s 是唯一的;list因?yàn)樵趧?chuàng)建新的之前原始的已經(jīng)消失了list,所以如果它們id在稍微不同的時(shí)間點(diǎn)具有相同的 s ,則不會(huì)違反任何保證。
測(cè)試的順序很重要,因?yàn)?code>id它本身是從小對(duì)象分配器中最近釋放的塊集中拉出的。這里的順序是:
原件
[1]分配在地址A的結(jié)果
[::-1]分配在地址B此后,
[1]分配 A 立即返回到 的list空閑列表中id返回int描述地址 BB的結(jié)果
[::-1]返回到空閑列表(在 A 之前)第二個(gè)
[1]是分配,獲取 B,之前使用的內(nèi)存[::-1]id被調(diào)用,準(zhǔn)確地產(chǎn)生id與以前相同的結(jié)果(因?yàn)?new[1]被賦予了最近從產(chǎn)生的內(nèi)存中釋放的內(nèi)存list[::-1]),因?yàn)閮蓚€(gè)lists 都使用地址 B
這實(shí)際上比需要的更復(fù)雜;id([1]) == id([1])最終也會(huì)得到相同的結(jié)果(它只會(huì)在空閑列表list上少留下一個(gè) s list)。
當(dāng)你以相反的方式做時(shí),會(huì)發(fā)生這種情況:
[1]分配在地址Aid返回一個(gè)新的int描述地址A[1]被釋放并且地址A返回到池中分配下一個(gè)
[1],獲得 A,與第一個(gè)相同的內(nèi)存[1][::-1]應(yīng)用于它,list從新鮮記憶 B 中獲取新的;[1]然后被扔掉id[::-1]根據(jù)獲取描述地址 B的結(jié)果進(jìn)行調(diào)用int;地址 A 和 B 的sid不匹配
如果您創(chuàng)建并存儲(chǔ)了這兩個(gè)lists,然后將id仍然存在的 slist相互比較,它們將是唯一的,因?yàn)檫@些內(nèi)存重用惡作劇將無法發(fā)生。
添加回答
舉報(bào)
