为什么Python中的id函数对于不同的整数对象返回相同的值?

suc*_*ntz 3 python memory-address python-3.x

我有一个使用 ctypes 模块在 Python 中检索对象的函数:

import ctypes

def object_at_addr(obj_addr):
    try:
        val = ctypes.cast(obj_addr, ctypes.py_object).value
    except:
        return None
    return val
Run Code Online (Sandbox Code Playgroud)

我知道id对象的 表示该对象所在的内存地址(就我在内置对象和自定义对象中看到的大部分而言)。在我的终端 shell 上,我对数字 0 进行了尝试,并“递归地”找到了id每个数字的 ,以查看它是否以某种形式循环。这是终端输出:

>>> id(0) # num1
4343595216
>>> id(4343595216) # num2
4344636112
>>> id(4344636112) # num3
4344636112 
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,两个号码的 id 是相同的。但是,当我使用我的函数和 call 时object_at_addr(4344636112),它并不指向任何一个数字,而是返回一个不同的 int 值,如下所示:

>>> object_at_addr(4344636112)
4411205344
Run Code Online (Sandbox Code Playgroud)

两个不同的号码怎么会有相同的id值呢?该函数是否id实际上返回所有对象的内存地址,还是仅适用于自定义对象,或者只是Python设计选择,使内存地址成为id对象的内存地址,但对于内置对象有所不同?

wim*_*wim 6

始终是idCPython 实现中的内存地址。您在这里看到具有相同 id 的数字的原因是内存地址可以重复使用。id 仅保证在对象的生命周期内是唯一的,并且由于没有其他任何东西保存对整数的引用,4343595216因此在函数调用返回后立即将其删除。该内存位置被释放,然后立即被整数4344636112实例重用。

文档实际上明确提到了这一点

具有不重叠生命周期的两个对象可能具有相同的id()值。