1 回答

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