首页 存档 技术 查看内容

Python源码剖析----Python的编译结果

2018-3-30 13:00 |来自: 互联网 300 0

摘要: 1.和java类似,Python文件在真正被执行之前需要被编译成字节码文件(pyc),然后由python虚拟机执行。每个文件在改变内容之前只会被编译一次,这和java也是一样的。java的源码编译之后得到的实际上得到的是PyCodeObj ...

1.和java类似,Python文件在真正被执行之前需要被编译成字节码文件(pyc),然后由python虚拟机执行。每个文件在改变内容之前只会被编译一次,这和java也是一样的。java的源码编译之后得到的实际上得到的是PyCodeObject对象,该对象被写入硬盘时的文件就是pyc文件。


2.并非每个python文件生成一个PyCodeObject对象,而是每个CodeBlock生成一个PyCodeObject对象。区分CodeBlock的方法是,当进入一个新的名字空间时,就进入了一个新的CodeBlock。例如:

[demo.py]

class A:

pass

def fun():

pass

a = A()

fun()

编译demo.py文件会生成3个PyCodeObject对象,一个对应整个文件,一个对应class A,最后一个对应函数fun


3.Python并不总是会生成pyc文件,如果直接在命令行中运行demo.py文件,会发现并没有在硬盘上生成pyc,原因可能是Python认为该段代码不会被再次执行。如果想生成其对于的pyc文件,只需要在文件头加上import demo(注意,python中可以import自己),再次运行就会生成pyc了。也就是说,import会激活生成pyc机制。


4.如果碰到import abc这样的语句时,python将到设定好的path中寻找abc.pyc或abc.dll文件,如果都没有,而只发现了abc.py, 那么python会首先将abc.py编译成相应的PyCodeObject的中间结果,然后创建abc.pyc文件,并将中间结果写入该文件。接下来Python才会进行import操作,实际上就是将abc.pyc文件中的PyCodeObject对象从内存中复制出来。


5.pyc文件的内容

实际上,pyc文件不只包含PyCodeobject对象,还包括其它信息。具体来说,包含三部分信息:

第一部分是magic_number,不同版本的python会定义不同的magic_number,这个数字是用来保证Python兼容性的。比如说,要防止Python2.5加载Python1.5产生的pyc文件,只需要将Python2.5的magic_number设置的和Python1.5不同即可

第二部分是生成pyc的时间,这个信息可以让Python自动将pyc文件与最新版本的py文件同步

最后一部分是PyCodeObject对象。

python学习交流群:330637182

6.每个py文件只会有一个PyCodeObject对象被写入pyc文件,但是每个py文件却会生成多个PyCodeObject对象,这样会导致丢失PyCodeObject对象吗?

答案是当然不会,Python的PyCodeObject是按照CodeBlock来区分的,每个文件最外层的Codeblock包含了所有其他的CodeBlock,因此其它的PyCodeObject对象时嵌入在最外层的PyCodeObject对象中的,实际上这些子PyCodeObject对象时存储在最外层PyCodeObject对象的co_consts域中的。写入pyc文件时,遇到新的PyCodeObject会递归写入。


声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部