gpt4 book ai didi

python - `[]` 和 `list()' 的行为有什么区别?

转载 作者:太空宇宙 更新时间:2023-11-03 12:43:30 25 4
gpt4 key购买 nike

print(id([]) == id([]))
# prints 'True'

print(id(list()) == id(list()))
# prints 'False'

x = []
y = []
print(id(x) == id(y))
# prints 'False'

对于上述代码,为什么 list() 的行为与 [] 不同?

最佳答案

在您的第三个 id 比较中,您正在比较具有重叠生命周期的两个对象的 ID 值。根据 id 函数的约定,这必须返回 False。您会看到与 list() 相同的行为。

在前两个 id 比较中,所涉及的对象具有不重叠的生命周期。具有非重叠生命周期的对象的 ID 值是否碰巧相同是一个实现细节,您不应该依赖它是一种方式还是另一种方式。行为如有更改,恕不另行通知。

在当前的 CPython 中,ID 值恰好与 [] 相同,因为 [] 使用 BUILD_LIST操作码,调用 C 函数 PyList_New , 并且 PyList_New 使用释放列表头结构的空闲列表来加速分配:

PyObject *
PyList_New(Py_ssize_t size)
{
...
if (numfree) {
numfree--;
op = free_list[numfree];
_Py_NewReference((PyObject *)op);

当列表被释放时,保存元素指针的缓冲区被释放,但是(直到最大空闲列表大小)头部保存关于对象类型、引用计数、容量等信息的信息。goes on the free list :

static void
list_dealloc(PyListObject *op)
{
...
if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op))
free_list[numfree++] = op;
else
Py_TYPE(op)->tp_free((PyObject *)op);
Py_TRASHCAN_SAFE_END(op)
}

由第一个 [] 创建的列表在第二个 [] 表达式之前死亡,因此它的 header 进入空闲列表,然后被第二个重用[]id 值基于此 header 的地址,因此两个列表具有相同的 ID 值。

相比之下,list()会经过tp_newtp_init,而list tp_newPyType_GenericNew,它不经过相同的空闲列表。 PyType_GenericNew 恰好将两个列表分配到不同的内存中,产生不同的 ID 值。

关于python - `[]` 和 `list()' 的行为有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55586070/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com