python源码阅读(一) 文件夹结构和PyObject
最近陷入咸鱼状态(虽然一直都是)。python3.6也出来了,想到自己还没有读过python的源代码,想着狠下心来读一下看看。然而水平实在有限,不敢说有彻底读懂,只能说是对源码的阅读和个人理解。欢迎各位朋友批评指正。
python 源码指的一般是CPython。CPython即用C语言实现Python及其解释器(JIT编译器),Jython是用Java语言来实现,Pypy是用Python来实现(准确说是个Python子集)。
我们可以在cpython的github项目的branch中下载到Cpython各个版本的源代码。
此处下载下来的源码包含有下面几个文件夹。^1
- Doc:包含python的文档
- Grammar:包含python语法分析器
- Include:包含python的C头文件
- Lib:python的基础库函数
- Mac:包含在Mac上使用的特殊文件
- Misc:包含不适合其他地方的文件,只是具有历史意义。
- Modules:python用到的C的模块
- Objects:多种内置类型的源文件
- Parser:python的分词器。
- PC:包含一些旧的PC的py端口,以及所有PC特有的python源文件
- PCbuilde:用于在Windows NT上安装python。
- Programs:二进制可执行文件的源代码
- Python:主要Python库的其他源文件
- Tools:包含一些在构建或扩展Python时有用的Python程序。包括pdb等
首先看Include文件夹。Python实现了哪些东西,首先是从object.h这个文件开始看起。106行:
1 | /* Nothing is actually declared to be a PyObject, but every pointer to |
注释的意思是:没有什么是确切被声明为PyObject的但是任何指向python对象的指针都可以被转换为一个PyObject指针。这时手动制造的派生。同样的每一个指向可变大小的Python对象也能转换为PyVarObject指针。
这就是一个python对象的基本内容,里面包含了
- _PyObject_HEAD_EXTRA,定义了指向内存堆中存活的对象的前驱后继的双向链表的结点。
1 | /* Define pointers to support a doubly-linked list of all live heap objects. */ |
- ob_refcnt 是一个引用计数器,其类型
Py_ssize_t
实际是一个64位的int。 - *ob_type 是一个指向类型对象的指针。类型对象指示函数的类型。在python使用type()函数就能找到当前对象的类型。
上面注释还提到的PyVarObject,其源代码就在PyObject下面:
1 | typedef struct { |
其包含了一个PyObject和一个指示数量的ob_size。
_typeobject
关于我们之前看到的指示对象的类型的TypeObject,实际上是一个类型的对象,也是由PyObject来表示的一个类。他的定义在object.h的大概346行:
1 | typedef struct _typeobject { |
定义的第一行指示了一个PyObject_VAR_HEAD,这实际上是一个
PyVarObject的宏(#define PyObject_VAR_HEAD PyVarObject ob_base;
)
之后的两行指示的是模块用于打印的名称和用于分配内存的大小。
1 | /* Methods to implement standard operations */ |
接着给出了一些标准操作的函数接口,包括了在python命令行输入dir(object)
所能看到的几乎全部,这都是需要实现的接口。
这个文件其它的部分大多都是一些宏定义的字段。(实际上整个文件夹都是这样)
这一部分暂时看到这里了,下次看一个别的文件。咸鱼也需要一点时间发酵一下别的。