教你阅读 Cpython 的源码
目录
第一部分-介绍 Cpython
源代码中有什么?
如何编译Cpython代码
编译器能做什么?
为什么 Cpython 是用C语言而是 Python 编写的?
Python语言的规范
Cpython 中的内存管理机制
结论
第二部分-Python 解释器进程
建立运行时配置
读取文件/输入
词法解析和句法解析
抽象语法树
结论
第三部分- Cpython 的编译器和执行循环
编译
执行
结论
第四部分-Cpython 中的对象
基础对象类型
Bool和Long Integer 类型
回顾Generator类型
结论
第五部分 Cpython标准库
Python 模块
Pyhton 和 C 模块
Cpython回归测试套件
安装用户自定C义版本
最后-Cpython 源代码:结论
在使用 Python 的过程中你是否有这些疑惑,使用字典查找内容,为什么比遍历一个列表要快得多?生成器如何在每次生成值时记住变量的状态?为什么使用Python时我们不用像其他语言那样分配内存?事实证明,CPython,是最流行的Python版本,运行时是用人类可读的C和Python代码编写的。
这篇文主要就是围绕着Cpython展开的,文章涵盖CPython内部原理背后的所有概念、它们的工作原理以及可视化的解释。
你将会学到的内容有:
- 学会阅读源码
- 从源代码编译 CPython
- 理解列表、字典和生成器等概念以及内部工作原理
- 运行测试套件
- 修改或升级 CPython 库的组件,或许在未来可以贡献 新的 Python 版本
这篇文章很长但是很有用,如果你决定要学习Cpython,那么希望你能看下去,你会发现这是一份不错的学习资料。
这篇文章总共分为5部分,你可以根据自己的时候合理的安排阅读时间。每一部分都要花一定的时间,通过自己去研究这里面的一些案例,你会感到一种成就感,因为你掌握了Python的核心概念,这使得你成为一名更好的Python程序员。
第一部分 介绍 Cpython
我们平时说的Python,其实大多都是指的Cpython,CPython是众多Python中的其中一种,初次之外还有Pypy,Jpython等。CPython 同样的作为官方使用的 Python版本,以及网上的众多案例。所以,这里我们主要说的是 Cpython。
注意:本文是针对CPython源代码的3.8.0b3版编写的。
源代码中有什么?
CPython源代码分发包含各种工具,库和组件。我们将在本文中探讨这些内容。
首先,我们将重点关注编译器。先从git上下载Cpython源代码.
git clone https://github.com/python/cpython cd cpython git checkout v3.8.0b3 #切换我们需要的分支
注意:如果你没有Git,可以直接从GitHub网站下载ZIP文件中的源代码。
解压我们下载的文件,其目录结构如下:
cpython/ │ ├── Doc ← 源代码文档说明 ├── Grammar ← 计算机可读的语言定义 ├── Include ← C语言头文件(头文件中一般放一些重复使用的代码) ├── Lib ← Python写的标准库文件 ├── Mac ← Mac支持的文件 ├── Misc ← 杂项 ├── Modules ← C写的标准库文件 ├── Objects ← 核心类型和对象模块 ├── Parser ← Python 解析器源码 ├── PC ← Windows 编译支持的文件 ├── PCbuild ← 老版本的Windows系统 编译支持的文件 ├── Programs ← Python 可执行文件和其他二进制文件的源代码 ├── Python ← CPython 解析器源码 └── Tools ← 用于构建或扩展 Python 的独立工具
接下来,我们将从源代码编译CPython。
此步骤需要C编译器和一些构建工具。不同的系统编译方法也不同,这里我用的是mac系统。
在macOS上编译CPython非常简单。在终端内,运行以下命令即可安装C编译器和工具包:
$ xcode-select --install
此命令将弹出一个提示,下载并安装一组工具,包括Git,Make和GNU C编译器。
你还需要一个 OpenSSL 的工作副本,用于从PyPi.org网站获取包。
如果你以后计划使用此版本来安装其他软件包,则需要进行SSL验证。
在macOS上安装OpenSSL的最简单方法是使用HomeBrew。
如果已经安装了HomeBrew,则可以使用brew install命令安装CPython的依赖项。
$ brew install openssl xz zlib
现在你已拥有依赖项,你可以运行Cpython目录下的configure脚本:
$ CPPFLAGS="-I$(brew --prefix zlib)/include" \ LDFLAGS="-L$(brew --prefix zlib)/lib" \ ./configure --with-openssl=$(brew --prefix openssl) --with-pydebug
上面的安装命令中,CPPFLAGS
是 c 和 c++ 编译器的选项,这里指定了 zlib 头文件的位置,LDFLAGS
是 gcc 等编译器会用到的一些优化参数,这里是指定了 zlib 库文件的位置,(brew --prefix openssl)
这一部分的意思是在终端里执行括号里的命令,显示 openssl
的安装路径,可以事先执行括号里的命令,用返回的结果替换 (brew --prefix openssl)
,效果是一样的,每一行行尾的反斜杠可以使换行时先不执行命令,而是把这三行内容当作一条命令执行。
运行完上面命令以后在存储库的根目录中会生成一个Makefile,你可以使用它来自动化构建过程。./configure
步骤只需要运行一次。
你可以通过运行以下命令来构建CPython二进制文件。
$ make -j2 -s
-j2标志允许make同时运行2个作业。如果你有4个内核,则可以将其更改为4. -s标志会阻止Makefile将其运行的每个命令打印到控制台。你可以删除它,输出的东西太多了。在构建期间,你可能会收到一些错误,在摘要中,它会通知你并非所有包都可以构建。
例如,_dbm,_sqlite3,_uuid,nis,ossaudiodev,spwd和_tkinter将无法使用这组指令构建。如果你不打算针对这些软件包进行开发,这个错误没什么影响。如果你实在需要可以参考:https://devguide.python.org/。
构建将花费几分钟并生成一个名为python.exe的二进制文件。每次改动源代码,都需要重新运行make进行编译。
python.exe二进制文件是CPython的调试二进制文件。执行下面命令可以看到Python的运行版本。
$ ./python.exe Python 3.8.0b3 (tags/v3.8.0b3:4336222407, Aug 21 2019, 10:00:03) [Clang 10.0.1 (clang-1001.0.46.4)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
(其实最新的已经到Python3.9了,我编译了一下效果如下)