标准的 Python 实现是用 C 语言编写的。这意味着每一个 Python 对象都是一个聪明的伪 C 语言结构体,该结构体不仅包含其值,还有其他信 息。
例如,当我们在 Python 中定义一个整型,例如 x = 10000 时, x 并不是一个 “ 原生 ” 整型,而是一个指针,指向一个 C 语言的复合结构 体,结构体里包含了一些值。查看 Python 3.4 的源代码,可以发现整型 (长整型)的定义,如下所示( C 语言的宏经过扩展之后):
struct _longobject {
long ob_refcnt;
PyTypeObject *ob_type;
size_t ob_size;
long ob_digit[1];
};
Python 3.4 中的一个整型实际上包括 4 个部分:
ob_refcnt 是一个引用计数,它帮助 Python 默默地处理内存的分 配和回收。
ob_type 将变量的类型编码。
ob_size 指定接下来的数据成员的大小。
ob_digit 包含我们希望 Python 变量表示的实际整型值。
这意味着与 C 语言这样的编译语言中的整型相比,在 Python 中存储一 个整型会有一些开销,如下图所示:
这里 PyObject_HEAD 是结构体中包含引用计数、类型编码和其他之前提到的内容的部分。
两者的差异在于 ,C 语言整型本质上是对应某个内存位置的标签,里面存储的字节会编码成整型。而 Python 的整型其实是一个指针,指向包 含这个 Python 对象所有信息的某个内存位置,其中包括可以转换成整 型的字节。由于 Python 的整型结构体里面还包含了大量额外的信息, 所以 Python 可以自由、动态地编码。但是, Python 类型中的这些额外 信息也会成为负担,在多个对象组合的结构体中尤其明显。