为什么28 字节最初用于任何低至1 的值?
我完全相信@bgusach answered that; Python 使用C 结构体来表示Python 世界中的对象,任何对象including ints:
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
PyObject_VAR_HEAD 是一个宏,在展开时会在结构中添加另一个字段(字段PyVarObject,专门用于具有某种长度概念的对象),ob_digits 是一个包含数字值的数组.大小的样板来自该结构,用于小 和 大 Python 数字。
为什么要增加4 字节?
因为,当创建更大的数字时,大小(以字节为单位)是sizeof(digit) 的倍数;你可以看到在_PyLong_New 中为新的longobject 分配内存是用PyObject_MALLOC 执行的:
/* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
sizeof(digit)*size. Previous incarnations of this code used
sizeof(PyVarObject) instead of the offsetof, but this risks being
incorrect in the presence of padding between the PyVarObject header
and the digits. */
if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
PyErr_SetString(PyExc_OverflowError,
"too many digits in integer");
return NULL;
}
result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) +
size*sizeof(digit));
offsetof(PyLongObject, ob_digit) 是与保存其值无关的长对象的“样板”(以字节为单位)。
digit 定义在将struct _longobject 作为typedef 用于uint32 的头文件中:
typedef uint32_t digit;
而sizeof(uint32_t) 是4 字节。这就是当 _PyLong_New 的 size 参数增加时,您会看到字节大小增加的数量。
当然,这正是CPython 选择实现它的方式。这是一个实现细节,因此您不会在 PEP 中找到太多信息。如果您能找到相应的线程,python-dev 邮件列表将举行实施讨论:-)。
无论哪种方式,您可能会在其他流行的实现中发现不同的行为,所以不要认为这是理所当然的。