PyO3
Rust 的 Python 绑定,包括用于创建原生 Python 扩展模块的工具。也支持从 Rust 二进制文件中运行和交互 Python 代码。
用法
需要 Rust 1.83 或更高版本。
PyO3 支持以下 Python 发行版:
- CPython 3.9 或更高版本
- PyPy 7.3 (Python 3.11+)
- GraalPy 25.0 或更高版本 (Python 3.12+)
你可以使用 PyO3 用 Rust 编写原生 Python 模块,或者在 Rust 二进制文件中嵌入 Python。以下部分将依次解释这些用法。
从 Python 中使用 Rust
PyO3 可用于生成原生 Python 模块。首次尝试的最简单方法是使用 maturin。maturin 是一个用于构建和发布基于 Rust 的 Python 包的工具,配置最少。以下步骤安装 maturin,使用它生成并构建一个新的 Python 包,然后启动 Python 以导入并执行包中的函数。
首先,按照以下命令创建一个包含新 Python virtualenv 的新目录,并使用 Python 的包管理器 pip 将 maturin 安装到虚拟环境中:
# (replace string_sum with the desired package name)
$ mkdir string_sum
$ cd string_sum
$ python -m venv .env
$ source .env/bin/activate
$ pip install maturin
仍然在此 string_sum 目录内,现在运行 maturin init。这将生成新的包源码。当被要求选择要使用的绑定类型时,请选择 pyo3 绑定:
$ maturin init
✔ 🤷 What kind of bindings to use? · pyo3
✨ Done! New project created string_sum
该命令生成的最重要的文件是 Cargo.toml 和 lib.rs,其大致内容如下:
Cargo.toml
[package]
name = "string_sum"
version = "0.1.0"
edition = "2021"
[lib]
# The name of the native library. This is the name which will be used in Python to import the
# library (i.e. `import string_sum`). If you change this, you must also change the name of the
# `#[pymodule]` in `src/lib.rs`.
name = "string_sum"
# "cdylib" is necessary to produce a shared library for Python to import from.
#
# Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
# to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
# crate-type = ["cdylib", "rlib"]
crate-type = ["cdylib"]
[dependencies]
pyo3 = "0.29.1"
src/lib.rs
/// A Python module implemented in Rust. The name of this module must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
#[pyo3::pymodule]
mod string_sum {
use pyo3::prelude::*;
/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
}
最后,运行 maturin develop。这将构建该包并将其安装到之前创建并激活的 Python 虚拟环境中。随后,该包即可从 python 中使用:
$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
'25'
在检查运行时性能时,运行 maturin develop --release 以启用优化进行构建。
若要修改该包,只需编辑 Rust 源代码,然后重新运行 maturin develop 以重新编译。
若要一次性复制粘贴执行所有操作,请使用以下 bash 脚本(将第一条命令中的 string_sum 替换为所需的包名):
mkdir string_sum && cd "$_"
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop
如果你希望运行 cargo test 或在 Cargo 工作区中使用此项目,并且遇到了链接器问题,常见问题解答 中有一些变通方法。
与 maturin 一样,可以使用 setuptools-rust 或 手动 进行构建。两者都比 maturin 提供更强的灵活性,但需要更多配置才能开始。
从 Rust 中使用 Python
要将 Python 嵌入到 Rust 二进制文件中,你需要确保你的 Python 安装包含一个共享库。以下步骤演示了如何确保这一点(针对 Ubuntu),然后给出一些运行嵌入式 Python 解释器的示例代码。
要在 Ubuntu 上安装 Python 共享库:
sudo apt install python3-dev
要在基于 RPM 的发行版(例如 Fedora、Red Hat、SuSE)上安装 Python 共享库,请安装 python3-devel 软件包。
使用 cargo new 启动一个新项目,并像这样将 pyo3 添加到 Cargo.toml 中:
[dependencies.pyo3]
version = "0.29.1"
# Enabling this cargo feature will cause PyO3 to start a Python interpreter on first call to `Python::attach`
features = ["auto-initialize"]
显示 sys.version 的值和当前用户名的示例程序:
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;
fn main() -> PyResult<()> {
Python::attach(|py| {
let sys = py.import("sys")?;
let version: String = sys.getattr("version")?.extract()?;
let locals = [("os", py.import("os")?)].into_py_dict(py)?;
let code = c"os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
let user: String = py.eval(code, None, Some(&locals))?.extract()?;
println!("Hello {}, I'm Python {}", user, version);
Ok(())
})
}
该指南有一个包含大量关于此主题示例的章节
工具和库
- maturin 使用 pyo3、rust-cpython 或 cffi 绑定构建并发布 crate,以及将 rust 二进制文件作为 python 包发布
- setuptools-rust 用于 Rust 支持的 Setuptools 插件。
- pyo3-built 一个简单的宏,用于将使用
builtcrate 获取的元数据暴露为 [PyDict - rust-numpy NumPy C-API 的 Rust 绑定
- dict-derive 派生 FromPyObject 以自动将 Python 字典转换为 Rust 结构体
- pyo3-log 从 Rust 到 Python 日志记录的桥接
- pythonize 用于将 Rust 对象转换为兼容 JSON 的 Python 对象的 Serde 序列化器
- pyo3-async-runtimes 用于与 Python 的 Asyncio 库和 Rust 的异步运行时互操作的实用工具。
- rustimport 直接从 Python 导入 Rust 文件或 crate,无需手动编译步骤。默认提供 pyo3 集成并自动生成 pyo3 绑定代码。
- pyo3-arrow 用于 pyo3 的轻量级 Apache Arrow 集成。
- pyo3-bytes
bytes与 pyo3 之间的集成。 - pyo3-object_store
object_store与pyo3之间的集成。
示例
-
anise 一款现代、高性能的航天器任务设计工具包,曾用于协助 Firefly Blue Ghost 于 2025 年 2 月 2 日在月球实现软着陆。
-
arro3 一个用于 Apache Arrow 的极简 Python 库,连接至 Rust arrow crate。
- arro3-compute
arro3-compute - arro3-core
arro3-core - arro3-io
arro3-io
- arro3-compute
-
bed-reader 简单高效地读写 PLINK BED 格式。
- 展示了 Rayon/ndarray::parallel(包括捕获错误、控制线程数)、Python 类型到 Rust 泛型的转换、Github Actions
-
blake3-py BLAKE3 加密哈希函数的 Python 绑定。
- 在 GitHub Actions 上为 MacOS、Linux、Windows 进行并行 构建,包括无 GIL 的 3.13t 轮子。
-
cellular_raza 一个基于细胞的智能体模拟框架,用于从零开始构建复杂模型。
-
connector-x 在 Rust 和 Python 中将数据从数据库加载到 DataFrame 的最快库。
-
cryptography 部分功能由 Rust 实现的 Python 加密库。
-
css-inline 使用 Rust 实现的 Python CSS 内联工具。
-
datafusion-python 绑定至 Apache Arrow 内存查询引擎 DataFusion 的 Python 库。
-
deltalake-python 基于 delta-rs 的原生 Delta Lake Python 绑定,支持 Pandas 集成。
-
fastuuid Rust UUID 库的 Python 绑定。
-
fast-paseto 高性能 PASETO (Platform-Agnostic Security Tokens) 实现,带有 Python 绑定。
-
feos Rust 中极速的热力学建模,具备完善的 Python 接口。
-
finalytics Rust 中的投资分析库 | Python。
-
forust 一个用 Rust 编写的轻量级梯度提升决策树库。
-
granian 用于 Python 应用的 Rust HTTP 服务器。
-
haem 一个用于处理生物信息学问题的 Python 库。
-
hifitime 一个高保真时间管理库,适用于广义相对论和时间膨胀至关重要的工程和科学应用。
-
html2text-rs 用于将 HTML 转换为标记或纯文本的 Python 库。
-
html-py-ever 通过 kuchiki 使用 html5ever 来加速 HTML 解析和 CSS 选择。
-
hudi-rs Apache Hudi 的原生 Rust 实现,带有 C++ 和 Python API 绑定。
-
inline-python 直接在 Rust 代码中内联 Python 代码。
-
johnnycanencrypt 支持 Yubikey 的 OpenPGP 库。
-
jsonschema 一个高性能的 Python JSON Schema 验证器。
-
mocpy 一个天文学 Python 库,提供用于描述单位球面上任意覆盖区域的数据结构。
-
obstore 最简单、最高吞吐量的 Python 接口,用于 Amazon S3、Google Cloud Storage、Azure Storage 及其他 S3 兼容 API,由 Rust 驱动。
-
opendal 一个数据访问层,允许用户以统一的方式轻松高效地从各种存储服务中检索数据。
-
orjson 快速的 Python JSON 库。
-
ormsgpack 快速的 Python msgpack 库。
-
pdfcrate 一个符合人体工程学的、高级的 PDF 生成库,适用于 Rust 和 Python —— 一种 Prawn 风格的布局 API,用于组合文档,而非低层 PDF 管道。
-
polars Rust | Python | Node.js 中的快速多线程 DataFrame 库。
-
pydantic-core 用 Rust 编写的 pydantic 核心验证逻辑。
-
primp 最快的 Python HTTP 客户端,可通过模拟其头部和 TLS/JA3/JA4/HTTP2 指纹来伪装 Web 浏览器。
-
quebec 一个基于数据库的 Python 后台任务队列,灵感来自 Rails 的 Solid Queue。
-
radiate: 用于遗传编程和进化算法的高性能进化引擎。
-
rateslib 一个使用 Rust 扩展的 Python 固定收益库。
-
river Python 中的在线机器学习,计算密集型统计算法由 Rust 实现。
-
robyn 一个具有 Rust 运行时的超快速异步 Python Web 框架。
-
rust-python-coverage 一个包含 Rust 和 Python 自动化测试覆盖率的 PyO3 示例项目。
-
rnet 带有黑魔法的异步 Python HTTP 客户端
-
sail 统一流式、批处理和 AI 工作负载,并兼容 Apache Spark。
-
tibs 一个简洁的二进制数据 Python 库。
-
tiktoken 一个用于 OpenAI 模型的快速 BPE 分词器。
-
tokenizers Hugging Face tokenizers (NLP) 的 Python 绑定,使用 Rust 编写。
-
tzfpy 一个将经度/纬度转换为时区名称的快速包。
-
toml-rs 一个使用 Rust 编写的高性能 Python TOML v1.0.0 和 v1.1.0 解析器。
-
utiles 快速的 Python 网络地图瓦片工具
文章与其他媒体
- (视频) 在自由线程版与普通 Python 3.13 中使用 Rust - 2025 年 6 月 4 日
- (视频) 五年间为 Rust 在 Python 中探索路径所习得的技术 - 2025 年 2 月 26 日
- (播客) 连接 Python 与 Rust:PyO3 维护者 David Hewitt 访谈 - 2024 年 8 月 30 日
- (视频) PyO3:从 Python 到 Rust 再返回 - 2024 年 7 月 3 日
- 使用 Rust 将 Python AST 解析速度提升 20 倍 - 2024 年 6 月 17 日
- (视频) Python 如何通过 PyO3 驾驭 Rust - 2024 年 5 月 18 日
- (视频) 结合 Rust 与 Python:兼得两者之长? - 2024 年 3 月 1 日
- (视频) 使用 PyO3 以 Rust 扩展 Python - 2023 年 12 月 16 日
- PyO3 + rust-numpy 一周(如何将数据管道速度提升 X 倍) - 2023 年 6 月 6 日
- (播客) 与 David Hewitt 谈 PyO3 - 2023 年 5 月 19 日
- 用不到 100 行 Rust 代码让 Python 提速 100 倍 - 2023 年 3 月 28 日
- Pydantic V2 如何利用 Rust 的超能力 - 2023 年 2 月 4 日
- 我们如何使用 PyO3 以 Rust 扩展 River 统计模块 - 2022 年 12 月 23 日
- 用 Rust 编写 Python 扩展的九条规则 - 2021 年 12 月 31 日
- 使用 PyO3 从 Python 调用 Rust - 2021 年 11 月 18 日
- davidhewitt 在 2021 年 Rust Manchester 聚会上的演讲 - 2021 年 8 月 19 日
- 逐步将小型 Python 项目移植到 Rust - 2021 年 4 月 29 日
- Vortexa - 将 Rust 集成到 Python - 2021 年 4 月 12 日
- 用 Rust 编写并发布 Python 模块 - 2020 年 8 月 2 日
贡献
欢迎大家为 PyO3 做出贡献!支持该项目的方式有很多,例如:
- 帮助 PyO3 用户解决 GitHub 和 Discord 上的问题
- 改进文档
- 编写功能和修复 bug
- 发布关于如何使用 PyO3 的博客和示例
我们的 贡献指南 和 架构指南 提供了更多资源,如果您愿意为 PyO3 贡献时间并正在寻找切入点。
如果您没有时间亲自贡献,但仍希望支持项目的未来发展,我们的一些维护者拥有 GitHub 赞助页面:
License
PyO3 采用 Apache-2.0 license 或 MIT license 授权,由您选择。
Python 采用 Python License 授权。
除非您明确声明其他情况,否则您有意提交以包含在 PyO3 中的任何贡献(如 Apache License 中所定义),均按上述方式双重授权,不附加任何额外条款或条件。