ad

《自己动手写 Python 虚拟机》_更理解虚拟机的意义_3.1 pyc 文件

网友投稿 74 2023-11-07

【摘要】 本书摘自《自己动手写 Python 虚拟机》一书中第3章,第1节,海纳编著。

3.1 pyc 文件

先准备一个 pyc 文件。新建一个名为 hello.py 的文件,内容如下:

print 1+2*3

然后执行 python-m compileall hello.py 命令,就可以得到 hello.pyc 文件。还 有一种办法:直接运行 python 命令,进入 CPython 的交互式界面,然后执行 import hello不管用什么办法,得到的 pyc 文件是一个最简单的字节码文件。在 Windows 系

《自己动手写 Python 虚拟机》_更理解虚拟机的意义_3.1 pyc 文件

统上,可以通过Notepad++ 、UltraEdit 等十六进制查看工具来打开 pyc 文件。在

Linux 系统上,可以通过hexdump 工具来查看这个文件的内容,如图3.1所示。

接下来讲解 pyc 文件的各个组成部分。

pye 文件开头的四个字节,代表一个整数,被称为魔数(magic number),用于标

识文件类型和版本。需要注意的是,文件中高字节存储在高位,低字节存储在低位,

由于整型是4个字节,所以,使用 python 2.7 编译得到的 pyc 文件的魔数就 是0xa0df303。

文件的创建时间也是4个字节,这个域的意义不大,不再详细解释,略过。接下 来一定会是一个字符c, 也就是十六进制的0x63,出现在第9个字节,这个字符的意 义是:接下来是一个 CodeObject 结构。下面来详细分析这个结构。

CodeObject 的第一个域是一个整数,代表参数个数,记为 argcount; 可以看到在 hello.pye 这个例子中,argcount 的值为0。第二个域也是一个整数,代表局部变量的 个数,记为 nlocals, 这个域也是0。第三个域代表执行这段 code 所使用的操作数栈, 其深度的最大值记为stacksize; 在现在的例子中,这个值是3。第四个域是code 的属 性值,记为 flags, 值为0x40。关于 flags, 后面的章节会详细讲到,这里先略过。

再接下来就是本节要介绍的重点——字节码,它是以一个字符s 开头的,接下来 是一个整数,代表了这段code 的字节码的长度。在 hexdump 的结果的第二行,在字 符s 后面紧跟着一个整数0xd, 这就代表了这段字节码的长度是13。接下来的13个 字节,就是字节码了。

在字节码之后是常量表,记为 consts, 其中存着程序所使用的所有常量。它是一 个元组,在现阶段,可以把它理解成一个列表或者数组。这个元组以字符‘(’作为开 头,紧接着的是一个整数,代表元组中的元素个数,可以看到常量表的元素个数为5。 接着就是常量表中的5个元素。第一个元素的类型由字符 i 表示,表示第一个元素 是一个整数,它的值是接下来的四个字节,也就是1。同样的,第二个、第三个元素类 型也由i表示,它们也都是整数,分别是2和3。读者肯定已经注意到了这就是在 hello.py 的代码里使用的三个整数。再接下来是一个字符N, 代表了Python 中的 None, 这里先不关心这个None 是什么,在后面实现对象系统的时候,自然就会知道 这个 None 是怎么来的。最后一个元素仍然是一个整数,其值为6。这个6并没有在 源代码里出现,它是哪里来的呢?等到后面把字节码全部搞清楚以后,就会理解这个 问题。

常量表到这里就结束了。接下来是变量表,记为 names 。由于这段 Python 源代 码中没用使用任何的变量,所以变量表为空。在一个‘(’字符之后,紧跟一个整数0, 代表变量表为空。

变量表之后则是参数列表。这一项只在函数和方法里有用,代表了函数的输入

参数,先忽略它。接下来还有两个空的元组,分别是 cell_var 和 free_var, 用于构建闭 包,也临时忽略它们。

再接下来则是一个字符‘s’, 前面介绍过这代表一个字符串,接下来是一个整数, 代表了字符串的长度,可以看到这个字符串的长度为8,其值为“hello.py”,代表了源 文件的名字。再接下来是一个字符‘t’, 它也是一个字符串,格式与‘s’ 是完全相同 的,代表当前 code 所属的模块。

最后一项也是一个字符串,以字符‘s’ 标志。它是一个名为 line number table的 结构,在实现 Traceback 时,要输出详细的调用栈,会用到这个数据结构,这里先 略过。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们 [email protected] 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:《Python学习笔记 从入门到实战》_更了解Python的途径之一_9.4.1 什么是闭包
下一篇:《Python学习笔记 从入门到实战》_更了解Python的途径之一_8.1 模块 包和迭代器
相关文章

 发表评论

暂时没有评论,来抢沙发吧~

×