为什么空列表的大小不是 0 字节?

Adi*_*tya 3 python list python-2.7 python-3.x python-internals

今天,我在Python 2.7.13 中运行了下面给出的代码,发现列表大小在为空时不是 0:

import sys
data = []
for k in range(n):
    a = len(data)
    b = sys.getsizeof(data)
    print('Length:{0:3d};Size in bytes:{1:4d}'.format(a,b))
    data.append(None)
Run Code Online (Sandbox Code Playgroud)

我机器上的输出:

Length: 0; Size in bytes : 72
Length: 1; Size in bytes : 104
Length: 2; Size in bytes : 104
Length: 3; Size in bytes : 104
Length: 4; Size in bytes : 104
Length: 5; Size in bytes : 136
Length: 6; Size in bytes : 136
Length: 7; Size in bytes : 136
Length: 8; Size in bytes : 136
Length: 9; Size in bytes : 200
Length: 10; Size in bytes : 200
Length: 11; Size in bytes : 200
Length: 12; Size in bytes : 200
Length: 13; Size in bytes : 200
Length: 14; Size in bytes : 200
Length: 15; Size in bytes : 200
Length: 16; Size in bytes : 200
Length: 17; Size in bytes : 272
Length: 18; Size in bytes : 272
Length: 19; Size in bytes : 272
Run Code Online (Sandbox Code Playgroud)

我想知道为什么会这样?

似乎 Python 正在为某些东西保留内存。那是什么东西??

Jim*_*ard 5

因为从 返回的列表大小sys.getsizeof不仅包括列表包含的元素。

Python 中的每个对象都由一个C-struct表示;这个结构包含指向所有使列表成为列表的东西的指针(主要是它的方法)。sys.getsizeof调用时也会考虑它。

您可以随时查看GitHub 上 CPython 存储库的 master 分支中的实现list.__sizeof__

static PyObject *
list___sizeof___impl(PyListObject *self)
{
    Py_ssize_t res;

    res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*);
    return PyLong_FromSsize_t(res);
}
Run Code Online (Sandbox Code Playgroud)

(修剪掉不相关的 arg 诊所输出。)

sizeof 对功能2.x做同样的事情。

返回值res还包括列表对象类型的大小_PyObject_SIZE(Py_Type(self))

由于 Python 中的一切都是对象,因此可以在任何地方观察到这种行为,例如 integer 0

>>> getsizeof(0)
24
Run Code Online (Sandbox Code Playgroud)

虽然您通常不会期望这一点,但当您意识到 Python 中的所有内容都有“额外的包袱”时,这是完全有道理的,这允许我们认为理所当然的行为。