文章目录

  • 0 背景
  • 1 打包为so文件
  • 2 问题
  • 3 扩展(对整个文件中的python代码进行打包)

0 背景

因为python是解释型语言,不能生成编译后的文件(如.o)。因此源代码的安全问题成了隐患,一半python文件编译后,为了加速运行生成的都是pyc二进制文件(容易反汇编回源代码),一种更好的方法为将python源代码转换为c代码,然后编译c为so文件。尽管IDA Pro能够对so文件进行反汇编,从而将二进制代码转化为汇编语言,利用IDA Pro神奇的F5功能还能将汇编语言反编译成c/c++程序。但是反编译出来的c/c++程序却是下面这样的。无论是看懂还是得到python源代码难度都增加了不少。

一般被编译成so文件的代码都是被调用的代码,不用于直接执行。

⚠️注意:编译成so文件后,so文件只能在和之前用来编译的python版本相同的python版本中运行。

1 打包为so文件

  • 0,准备:

首先需要安装如下相关包

python 安装:cython

pip install cython

linux 安装:python-devel,gcc

如果是centos版linux执行:

yum install python-devel
yum install gcc

如果是ubuntu版linux:

apt-get install python-devel
apt-get install gcc
  • 1,编写setup.py文件,内容如下:
#!/usr/bin/env python
# encoding = utf-8
from distutils.core import setup
from Cython.Build import cythonize
setup(name = 'testSo.app',ext_modules = cythonize(["cal.py", "hello.py"])# ext_modules = cythonize("/Users/mac/PycharmProjects/TestSo/main.py"),
)
  • 2,运行如下的指令,
python3 setup.py build_ext --inplace

得到的文件,

  • 3,使用的话,直接使用import导入对应的模块,使用即可。

例如,执行的py文件和so文件在同级目录下(其他文件可以删除),

#!/usr/bin/env python
# encoding=utf-8
from hello import hello
from sub import add
hello("jk")
add([1,2,3,4,5])

hello.py:

def hello(name):print(f"Hello {name}")

sub.py:

def add(*args):sum = 0for arg in args:for num in arg:sum += numprint(sum)

得到的结果:

如果so文件不和py文件在同一个目录下,则需要使用sys引入so的路径,然后使用。

# 引入so文件路径
import sys
sys.path.append("/usr/app/spark-2.4.7-bin-hadoop2.7/Spark2/test/bigData/transform/standard")
# 调用cal.so文件中的add方法
from  cal import add
add([1,2,3,4,5])

2 问题

如果遇到了,SyntaxError: Non-ASCII character '\xff' in file t.cpython-39-x86_64-linux-gnu.so on line 2, but no encoding declared;,则可以到网址解决 问题

3 扩展(对整个文件中的python代码进行打包)

效果:

思路:把文件夹中的代码都拷贝到结果文件中(忽略的文件中的文件就不拷贝,如果设置了非代码类配置文件就一起拷贝),然后把需要编译的文件夹路径放到list中,另外把__init__.py文件用同名的空文件替代,使用build_ext进行文件编译。

执行的指令(用于linux环境下):

python3 setup.py build_ext

setup.py:

import os
import sys
import shutil
import numpy
import tempfilefrom setuptools import setup
from setuptools.extension import Extensionfrom Cython.Build import cythonize
from Cython.Distutils import build_extimport platform
# 构建后存放的文件目录
build_root_dir = 'build/lib.' + platform.system().lower() + '-' + platform.machine() + '-' + str(sys.version_info.major) + '.' + str(sys.version_info.minor)print(build_root_dir)extensions = []
ignore_folders = ['build', 'test', 'tests']
conf_folders = ['conf']def get_root_path(root):if os.path.dirname(root) in ['', '.']: # 得到文件的文件路径return os.path.basename(root) # 返回path最后的文件名else:return get_root_path(os.path.dirname(root))def copy_file(src, dest):if os.path.exists(dest): # 目的文件存在返回returnif not os.path.exists(os.path.dirname(dest)): # 目的文件夹不存在,递归创建文件夹os.makedirs(os.path.dirname(dest))if os.path.isdir(src): # 判断某一路径是否为目录shutil.copytree(src, dest) # 拷贝整个文件夹(目的文件夹需要不存在,否则会失败)else:shutil.copyfile(src, dest) # 拷贝整个文件def touch_init_file(): # 在临时文件夹中创建initinit_file_name = os.path.join(tempfile.mkdtemp(), '__init__.py')with open(init_file_name, 'w'):passreturn init_file_nameinit_file = touch_init_file()
print(init_file)def compose_extensions(root='.'):for file_ in os.listdir(root): # 当前目录下的所有文件abs_file = os.path.join(root, file_) # 路径拼接if os.path.isfile(abs_file):if abs_file.endswith('.py'):extensions.append(Extension(get_root_path(abs_file) + '.*', [abs_file]))elif abs_file.endswith('.c') or abs_file.endswith('.pyc'):continueelse:copy_file(abs_file, os.path.join(build_root_dir, abs_file))if abs_file.endswith('__init__.py'): # 用空白的__init__.py替代原有的copy_file(init_file, os.path.join(build_root_dir, abs_file))else:if os.path.basename(abs_file) in ignore_folders: # 忽略的文件不拷贝continueif os.path.basename(abs_file) in conf_folders: # 配置文件一同拷贝copy_file(abs_file, os.path.join(build_root_dir, abs_file))compose_extensions(abs_file)compose_extensions()
os.remove(init_file)setup(name='my_project',version='1.0',ext_modules=cythonize(extensions,nthreads=16,compiler_directives=dict(always_allow_keywords=True),include_path=[numpy.get_include()]),cmdclass=dict(build_ext=build_ext))

将Python文件打包成so文件相关推荐

  1. Python代码打包成exe文件

    Python代码打包成exe文件:     安装pyinstaller     打包文件:cmd到文件目录下, 执行 pyinstaller -F test.py 注意:如果有调用的文件或配置文件,打 ...

  2. 把Python项目打包成exe文件

    我们很多时候,写好的程序需要打包成.exe文件才可以发给客户,那么今天我就来谈一谈,如何将一个写好的Python程序打包成exe文件! 首先,我们我们使用到的工具是python 3.7 和 Pyins ...

  3. 将Python文件打包成exe文件(超详细)

    首先,我们为什么要把Python文件打包成exe文件? 因为,Python文件需要Python IDE打开 而exe,就是一个程序,双击就开了! 岂不是妙哉? 基础准备 首先,打开终端,我们要下载打包 ...

  4. python - .py文件打包成.exe文件, 发送给别人

    python文件打包成.exe文件有两种方式 参考: pyinstaller打包 Nuitka打包 环境 环境 描述 OS Windows10 64位 python 3.7 pycharm 2019 ...

  5. 将ocx和DLL文件打包成cab文件,inf的编写

    From: http://icrwen.iteye.com/blog/1118766 http://blog.csdn.net/yimiyangguang1314/article/details/65 ...

  6. java文件打包jar文件_如何把JAVA文件打包成jar文件

    本文讲解了把java文件打包成jar文件的方法,经测试可行.由于作者没时间用批处理文件进行操作的方法没有列出来. (1)把一个java文件打包到当前目录   javac –d . *.java (2) ...

  7. ubuntu 16.04 文件打包成deb文件的方法

    ubuntu 16.04 文件打包成deb文件的方法 可使用的方法一dpkg-deb 一.创建打包空间 二.创建打包相关文件 三.制作deb包 可使用的方法一dpkg-deb 初步了解的第一种方法:创 ...

  8. 用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)

    目录 打包前置知识 一.什么是exe可执行文件? 二.为什么要将 Python 程序打包为 exe 可执行文件? 三.为什么 Python 程序不能直接运行呢? 四.我们用什么来打包 Python 文 ...

  9. python爬虫文件打包成exe文件

    前言: 最近想把写好的爬虫文件发给朋友,由于考虑到朋友电脑里没有运行环境,下载环境安装所需要的库实在是太麻烦了,所以直接打包成exe文件发给他,这样就算没有python环境也可以双击exe文件运行.这 ...

  10. 利用cx_Freeze将py文件打包成exe文件(图文全解)

    python是一个非常非常优秀的编程语言,它最大的特性就是跨平台.python程序几乎可以在所有常见的平台中进行使用,而且大部分无需修改任何代码!不过,python也有一点点小缺憾(这个是由于自身本质 ...

最新文章

  1. ORACLE中的imp和exp
  2. Java多线程--使用future进行异步编程
  3. Java日志性能那些事
  4. 如果没准备这些面试题,找工作还是缓一缓吧
  5. PHP类参数_100 个最常用的 PHP 函数
  6. ttysac1 java_基于Android的串口聊天室 (基于tiny4412) 一
  7. Java 异常Exception e中e的getMessage()和toString()以及 e.printStackTrace();方法的区别
  8. Python-Scikit learn保存机器学习训练的模型
  9. 编程制作动态壁纸的思路_Android自定义动态壁纸开发详解
  10. 穷举法破解密码-方法详解
  11. 卢卡斯定理求组合数(逆元+费马小定理+扩展欧几里得)
  12. uni-app学习 form表单(五)
  13. nginx平台初探(100%)
  14. linux deploy安装kali和磁盘扩容
  15. 学习编程从坚定路线开始
  16. tom猫变声原理解析
  17. axios 请求拦截器响应拦截器
  18. 《iPad开发从入门到精通》——6.4节收藏历史
  19. HDU-4069(Squiggly Sudoku)(Dancing Links + dfs)
  20. 邦纳光电开关MIAD9R

热门文章

  1. Jensen不等式的证明
  2. m6000查看端口状态_M6000常用维护命令
  3. BackTrack3(BT3破解wifi密码)
  4. 全网最新猎豹网校-快速掌握Python项目实战
  5. HPE server 如何利用SPP包升级BIOS方法合集
  6. 如何正确删除TFS上项目
  7. caj文件转pdf、QQ文件、微信视频
  8. 不能为属性:[commandName]找到setter 方法
  9. scrollTop以及页面回到顶部
  10. Linux下使用QQ