如何使用PyO3构建可发布到PyPI的Python与Rust混合开发包
Rust+PyO3 混合Python包实现方案
1. 标准项目目录结构
my_geometry_project/ ├── Cargo.toml # Rust项目配置 ├── pyproject.toml # Python打包配置 ├── src/ │ └── lib.rs # PyO3导出逻辑实现 └── my_geometry/ # 对外暴露的Python包目录 ├── __init__.py # 包导出控制 └── points.py # Python侧二次封装逻辑
2. 核心配置文件
Cargo.toml 配置
[package] name = "my-geometry" version = "0.1.0" edition = "2021" [lib] name = "_geometry" crate-type = ["cdylib"] [dependencies] pyo3 = { version = "0.20", features = ["extension-module"] }
pyproject.toml 配置
[build-system] requires = ["maturin>=1.0,<2.0"] build-backend = "maturin" [project] name = "my-geometry" version = "0.1.0" authors = [{"name" = "Your Name", "email" = "your@email.com"}] description = "Python geometry package with Rust acceleration" requires-python = ">=3.8"
3. Rust侧导出逻辑
src/lib.rs 代码实现:
use pyo3::prelude::*; #[pyclass(module = "my_geometry._geometry")] #[derive(Clone, Copy)] pub struct Point { x: f64, y: f64, } #[pymethods] impl Point { #[new] pub fn new(x: f64, y: f64) -> Self { Self { x, y } } // 供Python侧封装调用的内部方法 pub fn get_coords(&self) -> (f64, f64) { (self.x, self.y) } } #[pymodule] fn _geometry(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::<Point>()?; Ok(()) }
4. Python侧二次封装
my_geometry/points.py 实现
from typing import List, Tuple # 导入Rust编译生成的内部扩展模块 from my_geometry._geometry import Point class Points: _points: List[Point] def __init__(self, points: List[Tuple[float, float]]): self._points = [] for point in points: x, y = point self._points.append(Point(x, y)) # 对外暴露的公共方法 def get_all_coords(self) -> List[Tuple[float, float]]: return [p.get_coords() for p in self._points] def add_point(self, x: float, y: float) -> None: self._points.append(Point(x, y))
my_geometry/init.py 导出控制
仅对外暴露封装后的Python类,隐藏底层Rust实现:
from .points import Points __all__ = ["Points"]
5. 测试与发布流程
- 安装构建依赖:
pip install maturin twine - 本地开发测试:根目录执行
maturin develop --release,会直接将包安装到当前Python环境,可直接执行from my_geometry import Points验证功能 - 构建发布包:执行
maturin build --release,生成的兼容当前平台的wheel包会存放在target/wheels目录下 - 发布到PyPI:执行
twine upload target/wheels/*,输入PyPI账号密码即可完成发布
注意事项
- 若需要支持多平台分发,可使用官方CI模板自动构建全平台wheel包,无需手动适配各系统
- 若完全不需要对外暴露Rust导出的
Point类型,可在Python侧将其设为内部类型,所有对外接口仅返回Python原生类型 - 给
#[pyclass]添加module属性,可避免静态类型检查工具识别类型时报错
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

