作为Python爱好者,需要了解.py脚本的基本运行机制及特性:
在很多工作上Python的运行流程基本上取决于用户,因此源码不需要编译成二进制代码(否则无法实现大部分贴近用户的特性),而直接从源码运行程序。当我们运行python文件程序的时候,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码。
因此总的来说,它具有以下三条特性
- 源码距离底层更远(根据官方文档的解释。不说,你们也感觉得到。)
- 运行时都需要生成字节码,交由虚拟机执行。(你们问我虚拟机在哪儿?!你们也不看看各自都是用什么软件执行的!没错,就是解释器,别和我说是IDLE啊。虚拟机具体实现了由switch-case语句构成的框架函数PyEval_EvalFrameEx,刚刚说的字节码就是这货执行的。)
- 每次执行脚本,虚拟机总要多出加载和链接的流程。(所以呢,相比于编译型语言就有点慢了。这与“有丝分裂间期”一样,准备东西也要花时间啊!)
那么,有人要问了:“不是说,运行时总要生成字节码么!那,字节码都去哪儿了?”
咳咳,别急!容我先说说,虚拟机它是怎么执行脚本的:
- 完成模块的加载和链接;
- 将源代码翻译为PyCodeObject对象(这货就是字节码),并将其写入内存当中(方便CPU读取,起到加速程序运行的作用);
- 从上述内存空间中读取指令并执行;
- 程序结束后,根据命令行调用情况(即运行程序的方式)决定是否将PyCodeObject写回硬盘当中(也就是直接复制到.pyc或.pyo文件中);
- 之后若再次执行该脚本,则先检查本地是否有上述字节码文件。有则执行,否则重复上述步骤。
你看!在我们点击(或输入命令)运行脚本,并悠闲地喝咖啡时,“人家”虚拟机做了这么多的事情。不过,你有没有发现.pyc或.pyo文件是否生成,是取决于我们如何运行程序的(虽然我们不知道要怎么做)。
同样,有人会吐槽:“哼!为什么不直接生成这些文件,这样来得不是‘更快、更高、更强’!”
其实,虚拟机也是讲究效率的。毕竟对于