如何分离Rust功能库及基于PyO3封装的Python扩展模块
拆分Rust核心库与Python扩展包的方案
1. 拆分项目结构
把原单库拆分为两个独立的Rust crate,配合Python构建配置文件,形成如下结构:
my_project/Cargo.toml# Rust工作区配置,统一管理两个cratemy_rust_lib/Cargo.toml# 核心功能库的依赖配置src/lib.rs# 所有核心Rust功能实现
my_python_ext/Cargo.toml# Python绑定库的依赖配置(依赖核心库+PyO3)src/lib.rs# PyO3绑定代码
setup.py# setuptools-rust构建配置pyproject.toml# 可选,现代Python构建环境配置
2. 配置Rust核心库
核心库完全专注于功能实现,不引入任何Python相关依赖,是标准的Rust库:
my_rust_lib/Cargo.toml
[package] name = "my_rust_lib" version = "0.1.0" edition = "2021" [dependencies] # 仅添加核心功能所需的依赖,无PyO3相关内容
my_rust_lib/src/lib.rs
/// 核心功能示例:两数求和 pub fn add(a: i32, b: i32) -> i32 { a + b } // 其他核心业务逻辑...
3. 配置Python绑定库
这个crate只负责把核心库的API通过PyO3暴露给Python,不实现业务逻辑:
my_python_ext/Cargo.toml
[package] name = "my_python_ext" version = "0.1.0" edition = "2021" [dependencies] # 依赖本地的核心库 my_rust_lib = { path = "../my_rust_lib" } # PyO3依赖,启用extension-module特性 pyo3 = { version = "0.20", features = ["extension-module"] }
my_python_ext/src/lib.rs
use pyo3::prelude::*; // 导入核心库的功能 use my_rust_lib::add; #[pymodule] fn my_python_ext(_py: Python, m: &PyModule) -> PyResult<()> { // 将核心库的add函数绑定为Python可调用函数 #[pyfn(m, "add")] fn add_py(_py: Python, a: i32, b: i32) -> PyResult<i32> { Ok(add(a, b)) } // 绑定其他核心功能... Ok(()) }
Python构建配置
setup.py
from setuptools import setup from setuptools_rust import RustExtension setup( name="my_python_ext", version="0.1.0", # 指定Rust扩展模块的名称和Cargo配置路径 rust_extensions=[RustExtension("my_python_ext", path="Cargo.toml")], packages=[], zip_safe=False, )
可选:pyproject.toml(现代Python构建标准)
[build-system] requires = ["setuptools", "setuptools-rust", "wheel"] build-backend = "setuptools.build_meta"
4. 构建与使用
Rust生态用户
只需在自己项目的Cargo.toml中添加核心库依赖即可,完全不需要Python相关内容:
[dependencies] # 本地开发用路径依赖,发布到crates.io后改用版本号 my_rust_lib = { path = "../path/to/my_rust_lib" }
之后直接调用核心库的API:
use my_rust_lib::add; fn main() { println!("{}", add(2, 3)); // 输出5 }
Python用户
直接进入Python绑定库目录,用pip安装即可:
cd my_python_ext pip install .
安装完成后在Python中调用:
import my_python_ext print(my_python_ext.add(2, 3)) # 输出5
5. 发布说明
- 核心库
my_rust_lib可正常发布到crates.io,和普通Rust库无区别,不会携带任何Python依赖。 - Python包
my_python_ext发布到PyPI时,setuptools-rust会自动处理编译流程:用户若有Rust环境则现场编译,也可提前构建多平台预编译轮子上传,让无Rust环境的用户直接安装。
内容的提问来源于stack exchange,提问作者MusicalNinja
相关产品推荐
相关产品推荐

