Nuitka 将 Python 脚本封装为 .pyd 或 .so 文件
前言
- 由于本人水平有限,难免出现错漏,敬请批评改正。
- 更多精彩内容,可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏、人工智能混合编程实践专栏或我的个人主页查看
- 人工智能混合编程实践:C++调用Python ONNX进行YOLOv8推理
- 人工智能混合编程实践:C++调用封装好的DLL进行YOLOv8实例分割
- 人工智能混合编程实践:C++调用Python ONNX进行图像超分重建
- 人工智能混合编程实践:C++调用Python AgentOCR进行文本识别
- 通过计算实例简单地理解PatchCore异常检测
- Python将YOLO格式实例分割数据集转换为COCO格式实例分割数据集
- YOLOv8 Ultralytics:使用Ultralytics框架训练RT-DETR实时目标检测模型
- 基于DETR的人脸伪装检测
- YOLOv7训练自己的数据集(口罩检测)
- YOLOv8训练自己的数据集(足球检测)
- YOLOv5:TensorRT加速YOLOv5模型推理
- YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
- 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
- YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
- YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
- Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
- YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
- 使用Kaggle GPU资源免费体验Stable Diffusion开源项目
- Stable Diffusion:在服务器上部署使用Stable Diffusion WebUI进行AI绘图(v2.0)
- Stable Diffusion:使用自己的数据集微调训练LoRA模型(v2.0)
环境准备
安装 Python:确保已安装 Python 3.7 或更高版本。
安装 Nuitka:
pip install nuitka
验证安装:
nuitka --version
Windows 特定要求
- 需要安装 Microsoft Visual Studio Build Tools 或完整的 Visual Studio,以提供 C++ 编译器(MSVC)。
Linux/macOS 特定要求
Linux:需要安装 GCC 或 Clang 编译器及开发工具包。例如,在 Ubuntu/Debian 上:
sudo apt update && sudo apt install build-essential
macOS:需要安装 Xcode 命令行工具:
xcode-select --install
相关介绍
- Python是一种跨平台的计算机程序设计语言。是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。
- Python 语言因其简洁的语法和丰富的生态系统,在数据科学、Web 开发、自动化脚本等领域广受欢迎。然而,其解释执行的特性也带来了源码暴露、运行依赖完整 Python 环境等问题。对于希望保护核心算法逻辑、提升部分执行性能或简化模块分发的开发者而言,将 Python 代码编译为二进制扩展模块是一种有效的解决方案。
- Nuitka 是一个功能强大的开源 Python 编译器,它能够将 Python 代码转换为 C++ 代码,并最终编译成原生机器码。除了生成独立的可执行文件(.exe),Nuitka 的一个重要功能是将 Python 模块编译为平台特定的二进制扩展文件——在 Windows 上为
.pyd
文件,在 Linux/macOS 上为.so
文件(共享对象)。这些二进制文件可以像普通 Python 模块一样被import
导入,但其内部逻辑以二进制形式存在,大大增加了反向工程的难度。本教程将详细介绍如何使用 Nuitka 在不同操作系统上将 Python 脚本封装为.pyd
或.so
文件。
什么是 Nuitka?
Nuitka 是一个“实际”的 Python 编译器。它的工作原理是:
- 分析:解析 Python 源代码,构建抽象语法树(AST)。
- 翻译:将 Python AST 转换为等效的 C++ 代码。
- 编译:调用系统本地的 C++ 编译器(如 MSVC、GCC、Clang)将生成的 C++ 代码编译成原生机器码。
- 链接:生成最终的二进制文件(可执行文件或扩展模块)。
与 PyInstaller、cx_Freeze 等打包工具不同,Nuitka 不仅仅是将解释器和脚本捆绑在一起,而是真正地将 Python 代码编译成本地指令,从而带来潜在的性能提升和更强的代码保护。
什么是 .pyd 和 .so 文件?
.pyd 文件 (Windows):
.pyd
是 Python 在 Windows 平台上的扩展模块文件,本质上是一个动态链接库(DLL)。- 它遵循 Python C API 规范,可以被 Python 解释器通过
import
语句直接加载。 - 后缀名
.pyd
明确告诉 Python 这是一个扩展模块,而非普通的 DLL。
.so 文件 (Linux / macOS):
.so
是“Shared Object”的缩写,即共享对象文件,相当于 Windows 上的 DLL。- 在类 Unix 系统中,Python 扩展模块通常以
.so
为后缀。 - Python 解释器同样可以通过
import
加载.so
文件作为模块。
共同特点与优势:
- 代码保护:源代码被编译为二进制,难以直接阅读和反编译,有效保护知识产权。
- 性能提升:原生机器码执行速度通常优于解释执行的字节码,尤其在 CPU 密集型计算中表现更佳。
- 模块化部署:可将项目的核心功能模块编译为二进制,主程序仍用 Python 脚本编写,实现混合部署。
- 接口封装:对外提供稳定的 Python 接口,内部实现细节被隐藏。
为什么选择 Nuitka 生成 .pyd/.so?
- 高兼容性:Nuitka 力求完全兼容 CPython,支持绝大多数 Python 语法和标准库。
- 原生性能:生成真正的原生代码,性能优化潜力大。
- 跨平台支持:同一套命令可在不同平台生成对应的二进制模块(
.pyd
或.so
)。 - 活跃维护:拥有持续更新的开发团队和活跃的社区支持。
Nuitka 将 Python 脚本封装为 .pyd 或 .so 文件
准备 Python 脚本
创建一个名为 core_module.py
的文件,内容如下:
# core_module.py
"""
演示 Nuitka 编译为 .pyd/.so 的核心模块。
"""
def calculate_power(base, exponent):
"""计算 base 的 exponent 次方。"""
return base ** exponent
def process_data(data_list):
"""对数据列表进行简单处理(示例)。"""
return [x * 2 + 1 for x in data_list]
class DataProcessor:
"""数据处理器类。"""
def __init__(self, name):
self.name = name
self.processed_count = 0
def transform(self, value):
result = value ** 2 - value
self.processed_count += 1
return result
# 模块常量
VERSION = "1.0"
使用 Nuitka 编译为二进制模块
在命令行中,导航到 core_module.py
所在目录,执行以下命令:
nuitka --module core_module.py
# 或者
nuitka --module core_module.py --output-dir=dist
关键参数说明
--module
:核心参数,指示 Nuitka 将脚本编译为 Python 扩展模块。--output-dir=DIR
:指定输出目录。例如--output-dir=build
。--remove-output
:编译前自动清理旧的输出文件和临时目录。--lto
:启用链接时优化,可进一步提升性能(推荐)。--jobs=N
:指定并行编译的线程数,加快编译速度(N 为数字)。
推荐的完整命令:
nuitka --module --output-dir=dist --remove-output --lto --jobs=4 core_module.py
注意:该命令在 Windows 上会生成
core_module.pyd
,在 Linux/macOS 上会生成core_module.so
。Nuitka 会根据运行的操作系统自动选择正确的后缀。
等待编译完成
Nuitka 将执行代码转换、C++ 编译和链接过程。成功后,你将在输出目录(如 dist/
)中看到:
core_module.pyd
(Windows) 或core_module.so
(Linux/macOS)- 一个名为
core_module.build/
的临时目录(包含中间文件,可删除)
输出结果
文件生成与结构
编译成功后,你会得到平台特定的二进制模块文件:
- Windows:
core_module.pyd
- Linux/macOS:
core_module.so
该文件可以直接被 Python 解释器导入,就像导入一个普通的 .py
模块。
使用编译后的二进制模块
创建一个测试脚本 test_module.py
来验证编译后的模块:
# test_module.py
import core_module # 导入编译后的二进制模块
# 测试函数
power_result = core_module.calculate_power(2, 8)
print(f"2^8 = {power_result}")
processed_data = core_module.process_data([1, 2, 3, 4])
print(f"Processed data: {processed_data}")
# 测试类
processor = core_module.DataProcessor("MyProcessor")
transformed_value = processor.transform(5)
print(f"Transformed 5 -> {transformed_value}")
print(f"Processed count: {processor.processed_count}")
# 访问常量
print(f"Module version: {core_module.VERSION}")
运行测试
确保 test_module.py
与 core_module.pyd
(或 core_module.so
)位于同一目录,或 core_module
模块在 Python 的搜索路径中。
运行测试脚本:
python test_module.py
预期输出:
2^8 = 256
Processed data: [3, 5, 7, 9]
Transformed 5 -> 20
Processed count: 1
Module version: 1.0
如果输出正确,说明二进制模块已成功编译并可正常工作。
注意事项与常见问题
依赖管理:
- Nuitka 在编译
--module
时不会打包第三方依赖。运行时,Python 环境必须已安装所有必需的包(如numpy
,pandas
)。 - 对于复杂依赖,建议使用虚拟环境管理。
- Nuitka 在编译
路径与导入:
- 确保
.pyd
或.so
文件与导入它的脚本在同一目录,或位于PYTHONPATH
中。 - 文件名必须与模块名一致(不包括后缀)。
- 确保
编译器配置:
- 确保系统已正确安装 C++ 编译器(MSVC/GCC/Clang)。
- 在某些 Linux 发行版上,可能需要安装
python3-dev
包以获取 Python 头文件。
性能考量:
- 编译后的模块在 CPU 密集型任务中性能提升显著,但在 I/O 操作或简单逻辑中差异不大。
- 启用
--lto
通常能带来额外的性能增益。
调试与开发:
- 二进制模块无法进行源码级调试。务必在编译前充分测试
.py
版本。 - 可以结合使用:核心模块编译为
.pyd/.so
,外围逻辑保持为.py
脚本。
- 二进制模块无法进行源码级调试。务必在编译前充分测试
跨平台限制:
- 在 Windows 上生成的
.pyd
不能在 Linux 上使用。 - 在 Linux 上生成的
.so
也不能在 Windows 上使用。 - 必须在目标平台上进行编译。
- 在 Windows 上生成的
总结
Nuitka 提供了一种强大而灵活的方式,将 Python 代码编译为平台特定的二进制扩展模块(.pyd
或 .so
)。这不仅增强了代码的安全性,还可能带来性能上的好处。通过本教程,你应该已经掌握了从环境搭建、脚本编译到模块使用的完整流程。在实际项目中,可以将敏感算法、核心业务逻辑编译为二进制模块,而将配置、用户界面等部分保留为可读的 Python 脚本,从而在代码保护与开发效率之间取得良好平衡。随着 Nuitka 的持续发展,其对现代 Python 特性的支持和优化能力也在不断增强,是值得考虑的 Python 代码发布与保护方案。
参考
[1] https://nuitka.net/
- 由于本人水平有限,难免出现错漏,敬请批评改正。
- 更多精彩内容,可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏、人工智能混合编程实践专栏或我的个人主页查看
- 人工智能混合编程实践:C++调用Python ONNX进行YOLOv8推理
- 人工智能混合编程实践:C++调用封装好的DLL进行YOLOv8实例分割
- 人工智能混合编程实践:C++调用Python ONNX进行图像超分重建
- 人工智能混合编程实践:C++调用Python AgentOCR进行文本识别
- 通过计算实例简单地理解PatchCore异常检测
- Python将YOLO格式实例分割数据集转换为COCO格式实例分割数据集
- YOLOv8 Ultralytics:使用Ultralytics框架训练RT-DETR实时目标检测模型
- 基于DETR的人脸伪装检测
- YOLOv7训练自己的数据集(口罩检测)
- YOLOv8训练自己的数据集(足球检测)
- YOLOv5:TensorRT加速YOLOv5模型推理
- YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
- 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
- YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
- YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
- Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
- YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
- 使用Kaggle GPU资源免费体验Stable Diffusion开源项目
- Stable Diffusion:在服务器上部署使用Stable Diffusion WebUI进行AI绘图(v2.0)
- Stable Diffusion:使用自己的数据集微调训练LoRA模型(v2.0)