首页  >  文章  >  后端开发  >  为什么 CPython 中两个不同的对象可以具有相同的 ID,即使它们不是同一个对象?

为什么 CPython 中两个不同的对象可以具有相同的 ID,即使它们不是同一个对象?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-10-31 00:33:03775浏览

Why can two distinct objects in CPython have the same ID even though they are not the same object?

理解 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn