PPT中信息组织如何实现-英雄云拓展知识分享
159
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 系
统上,可以通过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 时,要输出详细的调用栈,会用到这个数据结构,这里先 略过。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们 18664393530@aliyun.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~