Python程序设计开发宝典
上QQ阅读APP看书,第一时间看更新

1.9 Python程序伪编译与打包

众所周知,Python是纯粹的自由软件,源代码和解释器CPython遵循GPL(GNU General Public License)协议。那么很自然会有人有这样的疑问:难道Python程序只能以源代码的方式来运行吗?能不能通过某种方式来保护自己的源代码呢?答案是肯定的。这方面的技术主要有两种:一种方法是把Python程序伪编译成扩展名为pyc的字节码文件;一种是通过py2exe、pyinstaller或者cx_Freeze对Python程序进行打包成为不同平台上的二进制可执行文件。

1.Python程序伪编译

可以使用py_compile模块的compile()函数或compileall模块的compile_file()函数对Python源程序文件进行伪编译得到扩展名为pyc的字节码以提高加载和运行速度,同时还可以隐藏源代码。假设有Python程序Stack.py文件,并已导入py_compile和compileall模块,那么常用的编译方法如下。

1)py_compile.compile('Stack.py')

等价于compileall.compile_file('Stack.py'),也等价于在命令提示符环境中执行命令python-m py_compile Stack.py,都会在__pycache__文件夹中生成文件Stack.cpython-35.pyc。

2)py_compile.compile('Stack.py', optimize=1)

等价于compileall.compile_file('Stack.py', optimize=1),也等价于在命令提示符环境中执行命令python-O-m py_compile Stack.py,属于优化编译,会在__pycache__文件夹中生成Stack.cpython-35.opt-1.pyc文件。

3)py_compile.compile('Stack.py', optimize=2)

等价于compileall.compile_file('Stack.py', optimize=2),也等价于在命令提示符环境中执行命令python-OO-m py_compile Stack.py,属于高级优化编译,会在__pycache__文件夹中生成文件Stack.cpython-35.opt-2.pyc。

此外,Python的compileall模块还提供了compile_dir()和compile_path()等方法,用来支持Python源程序文件的批量编译。

那么问题来了,是不是编译成.pyc文件以后真的无法查看源代码呢?实际上,还是有很多办法可以查看的。例如,可以使用Python扩展库uncompyle6或其他类似模块来完成这个功能。使用pip工具安装uncompyle6之后,可以使用下面的代码对上面生成的.pyc文件进行反编译得到源代码:

        uncompyle6.uncompyle_file('__pycache__\\Stack.cpython-35.opt-1.pyc',
                                  open('__pycache__\\Stack.py', 'w'))

另外,http://tool.lu/pyc/这个网站可以在线上传一个.pyc文件,然后可以得到Python源代码(个别地方可能不是非常准确,需要自己稍做调整),并且还提供了一定的代码美化功能,能够自动处理代码布局和排版规范。

2.Python程序打包

保护源代码的更好方式是把Python程序转换为二进制可执行程序之后再发布,这样还使得打包后的程序可以在没有安装Python环境和相应扩展库的系统中运行,极大地方便了用户。可以把Python程序打包为可执行程序的工具有py2exe(仅适用于Windows平台)、pyinstaller、cx_Freeze等。当然,打包之前首先应该保证Python程序可以正常运行,并且本机已安装了所有需要的扩展模块和相关的动态链接库文件。

以使用py2exe在Windows平台上打包Python程序为例,假设有Python源程序文件test.py,然后编写setup.py文件,内容为

        import distutils
        import py2exe
        distutils.core.setup(console=['test.py'])

然后在命令提示符下执行下面的命令:

     python setup.py py2exe

接下来就会看到控制台窗口中大量的提示内容飞快地闪过,这个过程会自动搜集test.py程序执行所依赖的所有支持文件,如果创建成功的话则会在当前文件夹下生成一个dist子文件夹,其中包含了最终程序执行所需要的所有内容。等待编译完成以后,将dist文件中的文件打包发布即可。当然,对于简单的Python程序,直接在命令提示符环境执行build_exe test.py就可以生成.exe可执行文件了。

对于控制台应用程序,要想转换为exe可执行程序直接套用上面的代码框架即可,只需要把

     distutils.core.setup(console=['test.py'])

这行代码中的文件名替换为自己的Python程序文件名即可。对于GUI应用程序,还需要将上面代码中的关键字console修改为windows。

另外一个比较好用的Python程序打包工具是pyinstaller,同时适用于Windows平台和Linux平台上Python程序的打包,使用pip工具安装之后在命令提示符环境中使用命令pyinstaller-F-w kousuan.pyw或者python pyinstaller-script.py-F-w kousuan. pyw即可将Python程序kousuan.pyw及其所有依赖包打包成为当前所用平台上的可执行文件。

如果使用cx_Freeze工具的话,假设有Python程序hello.py,在命令提示符环境执行python cxfreeze hello.py即可快速创建可执行程序并自动搜集依赖的包。除此之外,在Windows平台上cx_Freeze还支持制作.msi安装程序。