目录
重点:
- Python解释过程: source code --> byte code --> JVM
- JIT 加速原理: 执行的时候将 一部分byte code 编译成 机器代码,替换原来的代码
- 其他的Python实现: Cpython, JPython, IronPython, PyPy, Stackless…
- Frozen Binaries
Chap1: A Python Q&A Session
1.1 Downside
运行速度
简而言之,标准的python实现,是将源代码 编译成中间语言,叫做
byte code
, 然后再解释执行
为了提高python的运行速度的问题,可以将逻辑部分使用python
编写,而在需要性能的部分使用 C/C++编写,然后再粘合,比如 著名的 numpy
1.2 Python能做什么
- 系统编程
- GUI:
- tkinter
- PMW( 基于tkinter)
- wxPython(基于C++库)
- Dabo(基于tkinter,wxPython等)
- Qt的工具
- Internet Scripting
- Component Integration
- Database Programming
- pickle, PyMongo, SQLObject, SQLAlchemy
- Rapid Prototyping
- Numeric and Scientific Programming
。。。
1.3 How Is Python Developed and Supported?
Python开发者在网上通过源代码控制系统协调工作,每一次的变化都以一种正式协议的方式,其中包括写 PEP(Python Enhancement Proposal) 或者其他文件。
1.4 Python的长处
- 面向对象,面向过程,函数式编程
- 函数式编程特色: generators, comprehensions, closures, maps, decorators, anonymous function lambdas, and first-class function objects
- 免费
- 可移植
- 强大
- 和其他语言混合
- 易学易用
Chap2: How Python Runs Programs
2.1 Python 解释器
Python不仅是一门语言,也是一个编译器的名称。编译器是一个软件,用来执行其他的程序。当你写了一个Python程序时,python解释器能够阅读你的程序,并且执行这些命令。
当安装Python解释器的时候,它最少也包括了一个解释器程序和一些支持性library。
2.2 程序执行
2.2.1 从程序员角度
python程序只是文本文件。 python文件以.py
结尾,但是从技术上来说,只有当文件被import
的时候,才必须要求文件以.py
结尾 。程序由解释器一行一行执行。
2.2.2 从Python的角度
当让Python去运行脚本的时候,python要先执行一些步骤,才能够真正的运行你的代码。具体来说,先将代码编译成一些叫做byte code
的东西,然后将它交给virtual machine
a. Byte code compilation
Python内部在执行程序的时候,先将源代码编译成一种byte code
的格式,byte code
是一种底层的,和平台无关的源代码表示。一条python语句,会被转换成多条的byte code
指令。 这种转换是为了提升执行速度——Byte code
的运行比文本文件运行速度快很多。
如果python进程拥有机器上写的权限,那么它会把byte code
安装在 .pyc
结尾的中。
在Python3.2
版本以前,运行了几次程序后,我们将能在源文件的同一个目录下,看到这些编译后的文件; 而在3.2开始之后的版本,Python把会把这些.pyc byte code
放置在源文件目录下的__pycache__
文件夹下,并且根据创建它们的python版本来命名他们,比如:script.cpython-33.pyc
检查是否需要重新编译:
无论在何种model
(将在Chap21中细讲),下一次执行程序的时候,python会加载这些.pyc
并且跳过编译过程,只要源文件没有在上一次编译后进行过更改,并且没有使用和上一次编译 不同的python版本运行过代码。 具体步骤如下:
- 源代码改变: Python会自动检查源文件的上一次修改时间,去和
byte code
内容作比较,来判断是否需要重新编译 - Python版本变更:python也会根据
byte code
中的python版本信息,来决定这次是否需要重新编译
Python如果没有写权限
程序仍然会正确运行,但是这些byte code
会在产生之后,被读入内存中,然后在程序结束之后就被删除。
因为.pyc
文件能加速启动时间,所以在大项目中,最好确保python有写权限。
Byte code
能够独立于源代码, 如果没有源文件,只有.pyc
文件,那么程序也能执行。
byte code只在被引入时产生
只有被import
的文件,才会将对应的byte code
保存到文件中,最顶级的脚本程序入口文件不会被保存到文件,只会在内存中使用。
b.The Python Virtual Machine (PVM)
当程序被编译之后,byte code
就会交付给 Python Virtual Machine来运行。
PVM本身并不是一个别的程序,它不需要单独安装。PVM本身就是一个大的代码循环,遍历你的代码,一条条执行代码的操作,它是 Python运行的引擎。它是在Python系统中,真正执行脚本的组件。技术上来说,它是所谓Python Interpreter的最后一步。
c. Performance implications
Python代码不像完全编译的语言一样,直接编译成机器码,所以它的运行速度自然比机器代码要慢;但它因为有一步编译,所以它的执行速度又比纯解释性语言快。
The net effect is that pure Python code runs at speeds somewhere between those of a traditional compiled language and a traditional interpreted language
d. Development implications
python并不区分 开发环境 和 部署环境,记住Python只有Runtime。
exec
,eval
等 built-ins, 能够读取字符串,将其当作python代码运行
2.3 Execution Model Variations
上面讲的python执行模式反映的是一种标准的python实现,但并不是一定的。随着时间变化,会有其他的模式出现。
2.3.1 Python实现 的Alternatives
最基本的5种Python语言实现: CPython, Jython, IronPython, Stackless, and PyPy
- CPython: 最标准的实现。
- Jython(JPython): Python的另一种实现,为的是让python和Java结合在一起。 JPython包括一些Java类, 它们能将Python代码编译成 Java字节码,然后给JVM运行。 不如CPython速度快和稳定
- IronPython: 和JPython差不多,是给 .NET用的
- Stackless–Python for concurrency: 重新实现的加强版CPython,为的是Concurrency, 更适合
coroutine
,并且自己提供了microthreads
,比python自己的 线程和进程更好。 - PyPy–Python for speed: a drop-in replacement for CPython, 为的是让一部分程序运行更快, 提供了
Just-in-Time(JIT)
编译器以及更快快速的 Python实现,提供了 sandbox tool来运行不安全代码, 并且提供了之前Stackless
的系统。Just-in-Time(JIT)
编译器以及更快快速的 Python实现,提供了 sandbox tool来运行不安全代码, 并且提供了之前Stackless
的系统。
JIT 是 JVM的一个扩展,它把部分的
byte code
直接转换成机器代码,为了提高速度。 它是在程序运行的时候做的转换操作,并没有一个 预编译过程,并且JIT也能够 通过跟踪程序中每个对象的数据类型, 把动态类型的Python创建为 明确类型的机器代码。
2.3.2 Execution Optimization Tools
CPython及其之前提到的其他Python实现,在实现的时候都差不多: 将源代码编译成 byte code
, 然后再交给合适的 virtual machine执行。
其他系统,比如Cython hybrid, the Shed Skin C++ translator, and the just-in-time compilers in PyPy and Psyco
,试着进一步的优化这种 基本运行模式。
- Cython (A Python/C hybrid): is a hybrid language that combines Python code with the ability to call C functions and use C type declarations for variables, parameters, and class attributes. 尝试将python代码编译成C代码。
- Shed Skin (A Python-to-C++ translator): 试着将Python代码转换成C++代码,再由电脑上的C++编译器来编译执行。
- Psyco (The original just-in-time compiler): 运行的时候将
byte code
进一步转换成machine code,并且记录了对象的数据类型。运行的时候,Psyco通过记录各种传递对象的类型信息,来产生最优化、最有效率的 机器代码。机器代码产生后,它们就会替换掉原来的那部分byte code
来加快执行速度。 这个JIT和Java
的JIT不同,它是一种Specializing JIT Compiler, 它根据程序具体使用到的类型,在不同的情况下产生不同的机器代码。
2.3.3 Frozen Binaries
有工具可以把Python程序直接打包成 可执行文件:
- py2exe
- PyInstaller
- py2app
- freeze
- cx_freeze
Frozen binaries 打包就是把Python编译出来的 byte code
,PVM
,还有其他Python支持文件打包在一起。所以这个可执行文件中已经有了 Python环境,不需要机器本身自带环境了。
2.3.4 Future Possibility
- 也许会有直接把Python代码编译成 机器代码
- 也许会有新的
byte code
格式