Python源码剖析(0 编译Python)
来源:互联网 发布:数组词多音字组词 编辑:程序博客网 时间:2024/05/29 10:38
- 1 Python总体架构
- 2 Python源代码的组织
- 3 Windows环境下编译Python
- 4 UnixLinux环境下编译Python
- 5 修改Python源代码
- 6 通往Python之路
- 7 一些注意事项
这一系列的资料来源:Python源码剖析
0.1 Python总体架构
在图0-1的右边,是Python的运行时环境,包括对象/类型系统(Object/Type structures)、内存分配器(Memory Allocator)和运行时状态信息(Current State of Python)。运行时状态维护了解释器在执行字节码时不同的状态(比如正常状态和异常状态)之间切换的动作,我们可以将它视为一个巨大而复杂的有穷状态机。内存分配器则全权负责Python中创建对象时,对内存的申请工作,实际上它就是Python运行时与C中malloc的一层接口。而对象/类型系统则包含了Python中存在的各种内建对象,比如整数、list和dict,以及各种用户自定义的类型和对象。
在中间的部分,可以看到Python的核心——解释器(interpreter),或者称为虚拟机。在解析器中,箭头的方向指示了Python运行过程中的数据流方向。其中Scanner对应词法分析,将文件输入的Python源代码或从命令行输入的一行行Python代码切分为一个的token;Parser对应语法分析,在Scanner的分析结果上进行语法分析,建立抽象语法树(AST);Compiler是根据建立的AST生成指令集合——Python字节码(byte code),就像Java编译器和C#编译器所做的那样;最后由Code Evaluator来执行这些字节码。。因此,Code Evaluator又可以被称为虚拟机。
图中,在解释器与右边的对象/类型系统、内存分配器之间的箭头表示“使用”关系;而与运行时状态之间的箭头表示“修改”关系,即Python在执行的过程中会不断地修改当前解释器所处的状态,在不同的状态之间切换。
0.2 Python源代码的组织
剖析的对象是2006年12月19日正式发布的Python 2.5(2.5衍生版都差不多,自己用的好像是2.5.6)。
0.3 Windows环境下编译Python
在PCBuild目录下可以看到VS2003的工程文件,PCBuild8目录下是VS2005的工程文件。
由于我们剖析的只是Python的核心部分,不会涉及工程中的一些标准库和其他的模块,所以可以将它们从编译的列表中删除。点击配置对话框左边列表框中的“Configuration Properties”后,会出现当前配置为需要编译的子工程,取消多余的子工程的选中状态,只保留pythoncore和python的选中状态。
编译还是会失败,原因是我们还需要一个必要的文件,这个文件在Python2.5的源码包中没有提供,必须要通过编译make_buildinfo和make_versioninfo子工程(如图0-8所示)才能生成:
编译的结果都放在build(实际是WIN32DUB文件夹)文件夹下,主要有两个:python25.dll和python.exe。安装还没有解决,也有可能是版本的原因。
0.4 Unix/Linux环境下编译Python
./configure –prefix=<你期望Python安装到的目录的路径> makemake install
2.5安装错误。和2.6及以上的安装路径,库名均会不同。
0.5 修改Python源代码
在int_print中输出一个整数,可以将int_print修改成如下的函数:
[intobject.c] 在objects文件夹下static int int_print(PyIntObject *v, FILE *fp, int flags){ //add by Robert PyObject* str = PyString_FromString("i am in int_print"); PyObject_Print(str, stdout, 0); printf(“\n”); fprintf(fp, "%ld", v->ob_ival); return 0;}
输出:
>>>print 100
‘i am in int_print’
100
在PyObject_Print中,第二个参数指明的是输出目标。上面的例子使用了stdout,指定了输出目标为标准输出,当我们从命令行环境中激活Python时,没有问题,但是如果使用IDLE的话,就会发现,输出的信息没有了。原因是IDLE的输出目标已经不是stdout了,说明加入的输出代码失效了.
在Python中,有一个特性——可以自己重定向标准输出。下面的代码显示了如何输出到重定向后的标准输出:
static PyObject* int_repr(PyIntObject *v){ char buf[64] //add by Robert If(PyInt_AsLong(v) == -999) { PyObject* str = PyString_FromString("i am in int_repr"); PyObject* out = PySys_GetObject("stdout"); if(out != NULL) { PyObject_Print(str, stdout, 0); printf("\n"); } } ……}
PyInt_AsLong的功能是将Python的整数对象转换为C中的int值。
0.6 通往Python之路
将对Python源码的剖析分为下面三个部分:
- 第1部分:Python内建对象。主要内容是简要介绍Python对象模型,以及剖析主要内建对象,包括整数、字符串、list和dict。在对内建对象的剖析中,我们会深入其实现,细致地分析各种对象在C一级是如何被构建起来的。
- 第2部分:Python虚拟机。主要内容是分析Python虚拟机执行字节码指令的过程。在这一部分中,我们将看到Python是如何通过虚拟机实现各种表达式、控制流、异常机制、函数机制及类机制.
- 第3部分:Python高级话题。主要内容是剖析Python的运行环境以及一些高级话题。内容包括:Python运行环境的初始化、动态加载机制、多线程机制和内存管理机制。
0.7 一些注意事项
在Python 2.4的源码中,许多数值的类型都是int或long,而在Python 2.5的源码中,Python自定义了一个新的类型Py_ssize_t。一般的,凡出现这个类型的地方,都可以以int视之。
通常Python的源码中会使用PyObject_GC_New、PyObject_GC_Malloc、PyMem_MALLOC,PyObject_MALLOC等API。只要坚持一个原则,即凡是以New结尾的,都以C++中的new操作符视之;凡是以Malloc结尾的,都以C中的malloc操作符视之。
[PyString_FromString() in stringobject.c]op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);等效于:PyStringObject* op = (PyStringObject*)malloc(sizeof(PyStringObject)+size);[PyList_New() in listobject.c]op = PyObject_GC_New(PyListObject, &PyList_Type);等效于:PyListObject* op = new PyList_Type();op->ob_item = (PyObject **) PyMem_MALLOC(nbytes);等效于:op->ob_item = (PyObject **)malloc(nbytes);
在本书中,指针指向的内存块都是距离指针最近的向右或向下的那块内存,图0-13中给出了一个例子:
在图0-13中,深色的方块就是指针所指向的内存块
- Python源码剖析(0 编译Python)
- Python源码剖析[1] —— 编译Python
- 《python源码剖析》笔记 Python的编译结果
- 《Python源码剖析》上架
- 《Python源码剖析》 读后感
- Python源码剖析读书笔记
- python源码剖析 读书笔记
- 《Python源码剖析》读书笔记
- Python源码剖析----第一章
- Python源码剖析-Dict
- Python源码剖析-SmallPathon
- python源码剖析 0-1章
- Python 源码剖析(一)—— vs2013 编译 python 源码
- 《Python源码剖析》推荐序
- 《Python源码剖析》读书笔记(总)
- Python源码剖析----第二章
- 《Python源码剖析》学习笔记
- 《Python 源码剖析》之对象
- Nginx之基础入门
- python读取配置文件
- Mysql Order By 注入总结
- mmu访问权限
- Hibernate 关系映射案例(一对一关系,一对多关系,多对多关系)
- Python源码剖析(0 编译Python)
- Java面向对象总结
- pip 中的权限问题
- 文章标题
- 修改Linux系统中的IP常见方法
- 实验三 十进制转二进制
- Markdown中编写LaTeX数学公式
- 静态库与动态库
- 选太子