Python和Java的解释方式对比
Java:源代码 -> 编译成class -> Jvm解释运行
Python:源代码 -> Python解释器解释运行
我经常和身边的Java开发者开玩笑说:“Java真变态,别的语言都是要么直接编译要么直接解释,Java太另类了又编译又解释的......”
直接解释和编译后解释其实最大的区别就是源代码的安全性。
如果是直接解释源代码,那么源代码没有安全性可言,也就是任何一个人都可以打开源代码一看究竟,任何人都可以随意修改源代码。
事实上,Python和Java的解释方式是相同的,只是我们表面上看Python是直接解释源代码,而实际上python解释器只会加载字节码。细心的小伙伴肯定发现了这一点,当我们import某个模块时,总是会在模块所在的目录创建一个pycache目录,里面存放着被加载模块的字节码文件。
编译源代码有以下作用:
1、源代码保护(算法保护)/ 防止用户篡改源代码
2、解释器加载代码速度加快
pyc和pyo的生成方法
pyc的作用是用来跨平台使用的,和Java中的Class文件类似。pyc文件是一种字节码文件,可以加快Python解释器的加载速度,当然也可以用来做简单的防源码泄露保护。
pyo则是优化过后的字节码文件,不过pyo更像编译型语言里的中间文件。
我们可以通过Python提供的py_compile模块来进行源代码的编译。
py_compile模块只提供3个方法,分别是有关编译异常PyCompileError、有关编译compile、有关程序入口main
我们要用到的是compile方法,compile原形如下:
compile方法原形
compile(file, cfile=None, dfile=None, doraise=False, optimize=-1)
有5个参数:
file:必选参数,要编译的源文件
cfile:编译后的文件,默认在源文件目录下的pycache/源文件名.解释器类型-python版本.字节码类型
例如:pycache/abc.cpython-34.pyo
dfile:错误消息文件,默认和cfile一样
doraise:是否开启异常处理,默认False
编译案例:
准备源文件a.py和b.py,内容相同,就是一句print("python")代码
编写编译脚本:
import py_compile py_compile.compile(file = "a.py",cfile = "a.pyc",optimize=-1) py_compile.compile(file = "b.py",cfile = "b.pyo",optimize=1)
可见,字节码文件成功运行。
也可以直接通过Python加载模块来运行:
编译成pyc
python -m py_compile 源代码
编译成pyo
python -O -m py_compile 源代码
这确实可以简单地保护我们的代码,同时似乎看起来像是加密的效果,但是要注意,这不是加密,只是把源码变成优化后的字节码而已,如果想要获得源码,我们一样可以通过逆向编译来得到源码,目前有专门逆向Python字节码的工具存在。
如果需要编译整个目录内的所有源代码,请参考Python compileall