最近, 作者遇到一个需求, 需要把Python的工程部署到别的集群, 但是又要保证Python代码的安全性. 于是上网搜索, 搜到几个解决方案, 但是都不是符合需求. 综合搜到的几个解决方案, 最终作者采用了编译成so动态库的方式发布.
首先说一下搜到到几个解决方案, 以及它们的优缺点
编译成pyc发布
优点: 操作简单
缺点: 可以被反编译
cx_freeze
优点: 可以通过freeze命令直接把一个项目所有的依赖生成一个二进制, 所以部署到新的环境时, 十分方便
缺点: freeze命令如果工程项目很大的话, 速度非常慢, 而且其生成的Python代码其实也是pyc, 可以被反编译
pyminifier
优点: 通过代码混淆的方式保护代码的安全
缺点: 貌似, 只对单个文件的混淆其作用, 如果是一个工程项目就不好使了
cython编译成动态库
优点: 可以将代码编译成.so动态库, 起到代码保护的作用
缺点: 编译速度太慢了
综合以上几个优缺点, 作者最终选择了通过cython编译成动态库的方式, 来达到保护Python代码的目的, cython官方文档
说下具体的做法和原理:
cython首先会把python代码翻译成C语言代码, 然后cython在将其编译成.so动态库, 最后, 在编译好的build/lib.linux-x86_64-2.7(不同的平台和python版本这个目录是不一样, 作者的是linux平台, Python2.7版本)文件夹中, 直接引用即可.
但是这里有一个坑, 如果你编译的是一个Python的库, 那么你的build/lib.linux-x86_64-2.7中的库文件中, 每个库里必须有一个__init__.py文件, 所以, 下面的代码会首先进行一个把一个空的__init__.py文件拷贝到对应的库中的操作, 然后搜寻所有的.py文件, 将其编译成动态库, 然后把所有的非.py文件, 移动到原目录对应的位置. 下面是对应的转换的setup.py文件和例子<