理解 CPython 中相同的对象 ID
在 CPython 中,内置函数 id() 返回表示对象内存地址的唯一整数。有趣的是,在某些情况下,两个不同的对象可以具有相同的 ID,如以下示例所示:
<code class="python">tuple1 = () tuple2 = () dict1 = {} dict2 = {} list1 = [] list2 = [] # Tuples are immutable assert(id(tuple1) == id(tuple2)) # Dicts are mutable assert(id(dict1) != id(dict2)) # Lists are mutable too assert(id(list1) != id(list2)) # Unexpectedly, empty dicts and lists have the same ID assert(id({}) == id({})) assert(id([]) == id([]))</code>
行为背后的原因
这种奇特的现象这种现象的发生是由于 CPython 内存分配器的运行时行为及其处理对象创建和销毁的方式造成的。当调用 id({}) 时,CPython 会创建一个新的字典对象并将其分配到内存中的临时位置。然而,这个临时对象在 id() 函数返回其 ID 后立即被销毁。当调用下一个 id({}) 时,新字典可能恰好在与前一个字典相同的内存位置中创建,从而导致即使这些对象不同,也会产生相同的 ID。
这个推理是以下序列中观察到的行为进一步支持了这一点:
<code class="python">id([]) 4330909912 x = [] id(x) 4330909912 id([]) 4334243440</code>
可变性和缓存的影响
值得注意的是,可变性在此行为中起着间接作用。虽然可变对象(例如列表和字典)不符合代码对象缓存的条件,但不可变对象(例如空元组和某些字符串)可以。这意味着在同一个代码对象中,这些不可变对象将被重复使用,可能导致将相同的 ID 分配给不同的不可变对象。
Id 唯一性和对象生命周期
总之,对象的 ID 仅在其生命周期内是唯一的。一旦一个对象被销毁或在创建之前,另一个对象可能会被分配相同的 ID。这种行为强调了 CPython 中对象 ID 的短暂性,以及在底层 Python 实现的上下文中理解内存分配和对象创建动态的重要性。
以上是为什么 CPython 中两个不同的对象可以具有相同的 ID,即使它们不是同一个对象?的详细内容。更多信息请关注PHP中文网其他相关文章!