需求
首先 Python 是一种面向对象的解释型程序语言,运行 Python 程序时是将 *.py 编译为独有的二进制编码 pyc 文件,然后对 pyc 中的指令进行解释执行,但是对 pyc 文件进行反编译也是比较简单的,可直接反编译为源码。
如果将基于Python 的产品发布到外部时,需要对源码进行保护,不被 crtl c, ctrl v , 因此需要将python文件打成so文件。
另外就是 如果某些源码中包含 秘钥,key 等核心私密数据时,同样需要解决数据安全风险。
编译 py 为 .so 文件
准备工作
linux 环境:
yum install -y python-devel , gcc
python 安装: cython
pip3 install cython
编译目标文件为 so
目标文件
代码语言:javascript复制#!/usr/bin/env python
# -*- coding: UTF-8 -*-
KEY = 'WmsdofwmPsyqQXIkBp'
def ops_key(k):
if k == KEY:
result = True
else:
result = False
return result
设置 setup.py
代码语言:javascript复制from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize(["ops.py"]))
编译
代码语言:javascript复制python3 setup.py build_ext
creating build/lib.macosx-10.14-arm64-3.8
clang -bundle -undefined dynamic_lookup -arch arm64 -arch x86_64 -Wl,-headerpad,0x1000 build/temp.macosx-10.14-arm64-3.8/ops.o -o build/lib.macosx-10.14-arm64-3.8/ops.cpython-38-darwin.so
上述命令会在同级目录下生成 ops.c 的文件以及一个 build 文件夹,在 build 文件夹里面有temp 文件 还有我们所需要的编译好的 .so文件。直接拷贝复用 .so 文件即可。
测试
创建测试文件
当前目录只有文件 ops.cpython-38-darwin.so , 在ipython中调用 ops.py中的 函数 ops_key
代码语言:javascript复制In [4]: ls
build/ ops.cpython-38-darwin.so* setup.py
In [5]: ll
total 328
drwxr-xr-x 4 yangyi staff 128 10 20 23:54 build/
-rwxr-xr-x 1 yangyi staff 160789 10 20 23:54 ops.cpython-38-darwin.so*
-rw-r--r-- 1 yangyi staff 112 10 20 23:51 setup.py
In [6]: from ops import ops_key
In [7]: ops_key('11111')
Out[7]: False
In [8]: ops_key('WmsdofwmPsyqQXIkBp')
Out[8]: True
注意事项
如果要打包的文件里面有引用其他文件目录下的 py 程序,执行的时候 会报错 ,搜索了资料,目前还没解决, 比如 ops.py 文件中
代码语言:javascript复制#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from log_base import init_log ### 这一行会报错
alert_log = init_log('ops', 'info')
KEY = 'WmsdofwmPsyqQXIkBp'
def ops_key(k):
alert_log.info('this is a test func ')
if k == KEY:
result = True
else:
result = False
return result
代码语言:javascript复制### temp 目录下的内容
yangyi@yangyiDBA ~/python/temp ll
total 336
drwxr-xr-x 4 yangyi staff 128B 10 20 23:54 build
-rw-r--r-- 1 yangyi staff 314B 10 21 00:06 old.ops_mod.py
-rwxr-xr-x 1 yangyi staff 157K 10 20 23:54 ops.cpython-38-darwin.so
-rw-r--r-- 1 yangyi staff 116B 10 21 00:06 setup.py
drwxr-xr-x 4 yangyi staff 128B 10 21 00:11 util
### util 目录下的内容
yangyi@yangyiDBA ~/python/temp/util ll
total 328
-rw-r--r--@ 1 yangyi staff 1.8K 10 21 00:06 log_base.py
-rwxr-xr-x 1 yangyi staff 158K 10 21 00:08 ops_mod.cpython-38-darwin.so
### 从 其他文件夹 引用 util 中的 ops_mod so 文件
yangyi@yangyiDBA ~/python/temp ipython3
Python 3.8.9 (default, Apr 13 2022, 08:48:06)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.28.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from util.ops_mod import ops_key
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-1-2166f8144e2a> in <module>
----> 1 from util.ops_mod import ops_key
~/python/temp/util/ops_mod.cpython-38-darwin.so in init ops_mod()
ModuleNotFoundError: No module named 'log_base'
In [2]: