1.Python程序的执行过程
实际上Python和java,C#执行原理都可以用两个词概括,------虚拟机,字节码
Python有一个非常核心的东西,这个东西被称为解释器。当我运行一个程序时,例如 python my-program.py ,Python解释器立即被激活,然后开始执行,在运行之前,还要完成一个复制的工作,编译py.文件,结果主要产生一组Python的byte-code(字节码),然后将编译结果交给Python的虚拟机。
[demo.py]
class A:
pass
def fun():
pass
a = A()
fun()
当我们在执行demo.py时,编译结果会产生PyCodeObject对象和pyc文件。在程序运行期间,编译结果存在于内存的PyCodeObject对象中,而Python结束运行后,编译结果又被保存到了pyc文件,当下一次运行相同的程序时,Python会根据pyc文件中记录的编译结果直接建立内存中的PyCodeObject对象,而不用再次编译。
python中PyCodeObject的声明:
对于代码中的一个Code Block,会创建一个PyCodeObject对象与这段代码对应,对应上文的demo.py,编译完成后总共会创建三个PyCodeObject对象,一个对应demo.py整个文件的,一个是对应class A所代表的Code Block,而最后一个对应def Fun所代表的Code Block.
2.pyc文件
每一个PyCodeObject对象中包含了每一个Code Block中Python源代码经过编译后得到的byte code序列。而前面提到,Python会将这些字节码序列和PyCodeObject对象一起存储在pyc文件。但是我们在命令行敲下python demo.py时并没有生成pyc文件,原因是有写程序可能执行一次就再也不执行了,没必要生成其对应的pyc文件。但是假如碰到import demo的动态加载动作之后,python就会产生pyc文件了。意味着如果Python碰到import demo语句,会首先到设定好的PATH中寻找abc.pyc。如果没有,只发现了demo.py,那么就会编译成PyCodeObject对应的中间结果,然后创建pyc文件,接下来Python才会对abc.pyc进行import动作。
其实pyc是一个二进制文件,那么python如何解释这一堆看上去毫无意义的字节流就至关重要了。要了解pyc文件的格式,首先必须要清楚PyCodeObject中每一个域都表示什么含义。