Python公开课 - 解释器详解
前言
解释器就是帮助我们将Python代码,也就是.py文件,交给机器可以执行的工具。
解释型语言与编译型语言
通常我们将Python和Java语音归为解释型语言,而对于C/C++则归为编译型语音,为什么这样划分呢,以下的一张图可以很好的说明
编译型
- 用户提交源码
- 编译器将源码编译成机器语音,但是这时候还不能执行,因为缺少启动代码和相关的库代码
- 针对2中的问题,连接器上场了,他主要用来找到以上缺少的代码,并进行组装成最后机器可以直接运行的可执行文件
解释型
- 用户提交源码
- 解释器将源码转化为字节码,在Python中一般为.pyc文件,在Java中则是.class文件了,这个字节码机器不能执行的
- 如果要执行字节码,则虚拟机上场了,这里需要强调一下,这个虚拟机不是vmware或者virtualbox的虚拟机概念,在Python中由虚拟机来执行这些字节码,在Java中同样是由JVM来实现,由于2中的字节码一般是不依赖于操作系统的,所以可以做到跨平台运行,也就是跨平台这件事,有虚拟机来搞定了
Python中的几种解释器
CPython
CPython是标准Python,也是其他Python编译器的参考实现。通常提到“Python”一词,都是指CPython。CPython由C编写,将Python源码编译成CPython字节码,由虚拟机解释执行。没有用到JIT等技术,垃圾回收方面采用的是引用计数。
Jython
Jython在JVM上实现的Python,由Java编写。Jython将Python源码编译成JVM字节码,由JVM执行对应的字节码。因此能很好的与JVM集成,比如利用JVM的垃圾回收和JIT,直接导入并调用JVM上其他语言编写的库和函数。
对于在Ubuntu上体验使用Jython的同学,可以按照以下步骤来进行
- 安装Jython环境
apt-get install jython
- 在命令行键入
jython
,则可以进入命令行模式
两个实际例子说明:
引用标准Java库
>>>from java.util import Date >>>d = Date() >>>print(d) Thu Dec 20 22:27:56 EST 2018
自定义Java库
- 编辑HelloWorld.java文件
package foo; public class HelloWorld { public void hello() { System.out.println("Hello World!"); } public void hello(String name) { System.out.printf("Hello %s!", name); } }
- 编译
javac HelloWorld.java
- 将生成的HelloWorld.class放入foo目录下
- 进入Jython环境,引入自定义包
>>> from foo import HelloWorld >>> h = HelloWorld() >>> h.hello("TutorialsPoint") Hello TutorialsPoint!
IronPython IronPython与Jython类似,所不同的是IronPython在CLR上实现了Python,即面向.NET平台,由C#编写。IronPython将源码编译成TODO CLR,同样能很好的与.NET平台集成。即与Jython相同,可以利用.NET框架的JIT、垃圾回收等功能,能导入并调用.NET上其他语言编写的库和函数。IronPython默认使用Unicode字符串。
PyPy 这里说的PyPy是指使用RPython实现,利用Tracing JIT技术实现的Python,而不是RPython工具链。PyPy可以选择多种垃圾回收方式,如标记清除、标记压缩、分代等。相对于CPython,PyPy的性能提升非常明显,但对第三方模块的支持不够。比如无法很好的支持使用CPython的C API编写的扩展。
Python的优化
一般来说,受限于语言的特性,相比与Java,Python属于动态数据类型,也就是说存在于内存中的数据,并不是像Java那样一开始就是与类型强绑定的,这样也要求Python中的虚拟机要进行数据类型检查,也就消耗了性能。
优化的方式很多,可以考虑通过Cython来进行优化,来提升到接近C的性能,这个会在后面的章节中涉及。
小结
Python的解释器很多,但使用最广泛的还是CPython。如果要跨平台跨网络的话,小T老师建议还是通过REST或者RPC来实现,比较简单。