终极教程:用Setuptools-rust和PyO3打造Python Rust扩展模块
写 Python 的你,是否曾经为某个循环太慢而焦虑?把热点代码用 setuptools-rust 重写成 Python Rust 扩展模块,运行速度能提升几个数量级,而打包发布却和纯 Python 一样简单。本教程将手把手带你从零开始,用 PyO3 编写 Rust 函数、用 setuptools-rust 完成编译与分发,打造属于你自己的高性能扩展模块。整个过程只需四步:装环境、写代码、配配置、跑安装,零基础也能轻松上手。
为什么你需要一个 Python Rust 扩展模块?
- 🚀 性能飞跃:计算密集任务可提速 10~100 倍,Rust 无 GC、零开销抽象,性能与 C 相当
- 🛡️ 内存安全:Rust 编译器在编译期就挡住空指针、数据竞争等隐患,比手写 C 扩展更安心
- 📦 一键分发:setuptools-rust 是 setuptools 的插件,编译、打包、上传 PyPI 一气呵成
- 🔗 双向调用:Python 调 Rust 函数,Rust 里也能回调 Python,生态互通无压力
核心工具速览:setuptools-rust 与 PyO3
| 工具 | 作用 | 类比 |
|---|---|---|
| PyO3 | 用 Rust 编写 Python 扩展的绑定库,提供 #[pymodule]、#[pyfunction] 等宏 | Rust 世界的 Cython |
| setuptools-rust | setuptools 插件,负责调用 Cargo 编译并生成可分发的扩展 | Rust 版的 C 扩展编译插件 |
setuptools-rust 的核心类 RustExtension 定义在源码 setuptools_rust/extension.py 中,它把 Cargo.toml 里的 lib 目标与 Python 模块一一对应;RustBin 则负责把 Rust 可执行文件装进虚拟环境。所有公开 API 汇总在 setuptools_rust/init.py 中,后续有需求可直接查阅。
第一步:快速安装与配置环境
安装前请确认本机已有 Python 3.7+ 和 Rust 工具链(rustup 安装即可)。然后创建一个虚拟环境并安装依赖:
python -m venv .venv
source .venv/bin/activate # Windows 用 .venv\Scripts\activate
pip install setuptools setuptools-rust
提示:setuptools-rust 会自动调用系统里的 cargo,无需手动安装 Python 包之外的任何东西。
想快速体验官方示例,可以 clone 示例仓库(仓库地址:https://gitcode.com/gh_mirrors/se/setuptools-rust),重点看 examples/hello-world/ 目录,那是本教程的完整版。
第二步:搭建项目结构
推荐采用「Python 包与 Rust 源码分离」的目录布局,官方 examples/hello-world 示例正是这种结构:
hello-world
├── python
│ └── hello_world
│ └── __init__.py
└── rust
└── lib.rs
python/放纯 Python 包,对外暴露友好 APIrust/放 Rust 源码,编译产物作为私有子模块被 Python 包引用
第三步:编写 Rust 扩展代码
打开 rust/lib.rs,用 PyO3 定义一个 sum_as_string 函数(完整源码见 examples/hello-world/rust/lib.rs):
use pyo3::prelude::*;
#[pymodule]
mod _lib {
use pyo3::prelude::*;
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
}
三个关键点:
#[pymodule]宏声明的模块名_lib必须与 Cargo.toml 中lib.name一致#[pyfunction]标记的函数可直接被 Python 调用,入参出参自动转换类型- 命名约定:模块名以下划线开头,表示「私有扩展」,由 Python 包包装后对外提供
第四步:配置 Cargo.toml 关键参数
在项目根目录创建 Cargo.toml(参见 examples/hello-world/Cargo.toml):
[package]
name = "hello-world"
version = "0.1.0"
edition = "2021"
[dependencies]
pyo3 = "0.28"
[lib]
name = "_lib"
crate-type = ["cdylib"] # 必须!编译成 Python 可导入的动态库
path = "rust/lib.rs"
crate-type = ["cdylib"]是核心,少了它 Python 无法 import- 一个 Cargo.toml 只允许一个
[lib],多扩展需拆多个 Cargo.toml 或用 PyO3 子模块
第五步:配置 pyproject.toml 核心步骤
pyproject.toml 是连接 Python 与 Rust 的桥梁(完整示例见 examples/hello-world/pyproject.toml):
[build-system]
requires = ["setuptools", "setuptools-rust"]
build-backend = "setuptools.build_meta"
[project]
name = "hello-world"
version = "1.0"
[tool.setuptools.packages]
find = { where = ["python"] }
[[tool.setuptools-rust.ext-modules]]
target = "hello_world._lib" # 扩展模块的完整点分名
binding = "PyO3" # 绑定方式,默认值可省略
配置要点:
[[tool.setuptools-rust.ext-modules]]是「表数组」,可同时声明多个扩展模块target最后一段_lib必须匹配 Cargo.toml 的lib.name- 若使用传统
setup.py方式,等价写法见 examples/hello-world-setuppy/setup.py,本质是构造RustExtension对象
第六步:一键安装与测试
在项目根目录执行:
pip install -e .
setuptools-rust 会自动调用 cargo 以 release 模式编译,然后像普通包一样装入环境。测试一下:
import hello_world
from hello_world._lib import sum_as_string
print(sum_as_string(3, 5)) # 输出 "8"
也可以像示例那样用 Python 封装 CLI(见 examples/hello-world/python/hello_world/sum_cli.py),把 Rust 函数包装成命令行工具。
进阶技巧:发布与性能调优
掌握基础后,这些进阶技巧能让你的扩展模块走向生产环境:
| 场景 | 推荐方案 |
|---|---|
| 构建可分发的 wheel | python -m build,详见官方文档 docs/building_wheels.md |
| 一套二进制兼容多版本 Python | 配置 [bdist_wheel] py_limited_api=cp37,构建 ABI3 wheel |
| Linux 多平台发布 | 使用 manylinux Docker 容器构建 |
| macOS 通用二进制 | 设置 ARCHFLAGS="-arch x86_64 -arch arm64" |
| 交叉编译 | 配合 cross / crossenv / cargo-zigbuild 实现 |
| 发布 Rust 可执行文件 | 改用 [[tool.setuptools-rust.bins]] 配置 |
常用环境变量:SETUPTOOLS_RUST_CARGO_PROFILE 可覆盖构建 profile,默认 release,设为 dev 可做调试构建。
常见问题与排错锦囊
- ❌ ImportError: cannot import name '_lib':检查 Cargo.toml 的
lib.name、lib.rs模块名、pyproject.toml 的target三者是否一致 - ❌ 找不到 cargo 命令:确认已安装 Rust 工具链,或通过
CARGO环境变量指定 cargo 路径 - ❌ 编译特别慢:首次编译需下载依赖,属正常现象;增量构建会快很多
- ❌ Windows 下 DLL 加载失败:确认使用的是 64 位工具链,且 Python 与 Rust 架构一致
总结:你的 Rust 加速之旅正式开启
至此,你已经掌握了用 setuptools-rust 和 PyO3 打造 Python Rust 扩展模块 的完整流程:搭环境 → 写 Rust 代码 → 配置两个清单文件 → 一键安装 → 打包发布。从官方 examples/ 目录里的 hello-world、html-py-ever、rust_with_cffi 等示例出发,边改边学,很快你就能把自己的性能瓶颈变成毫秒级的闪电体验。现在就动手,给你的 Python 项目装上 Rust 引擎吧!⚡
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



