83个版本
0.22.2 | 2024年7月17日 |
---|---|
0.22.0 | 2024年6月24日 |
0.21.0 | 2024年3月25日 |
0.20.1 | 2023年12月30日 |
0.1.0 | 2017年7月23日 |
#2 in FFI
3,383,436 每月下载量
用于 1,012 个包 (706 直接)
2MB
44K SLoC
PyO3
Rust 对 Python 的绑定,包括创建原生Python扩展模块的工具。支持在Rust二进制文件中运行和与Python代码交互。
用法
PyO3支持以下软件版本
- Python 3.7及更高版本(CPython、PyPy和GraalPy)
- Rust 1.63及更高版本
您可以使用PyO3在Rust中编写原生Python模块,或将Python嵌入到Rust二进制文件中。以下各节将分别解释这些用法。
从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 = { version = "0.22.2", features = ["extension-module"] }
src/lib.rs
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())
}
/// A Python module implemented in Rust. The name of this function must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
#[pymodule]
fn string_sum(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
Ok(())
}
最后,运行 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'
要修改包,只需编辑 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.22.2"
features = ["auto-initialize"]
示例程序显示 sys.version
的值和当前用户名
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;
fn main() -> PyResult<()> {
Python::with_gil(|py| {
let sys = py.import_bound("sys")?;
let version: String = sys.getattr("version")?.extract()?;
let locals = [("os", py.import_bound("os")?)].into_py_dict_bound(py);
let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
let user: String = py.eval_bound(code, None, Some(&locals))?.extract()?;
println!("Hello {}, I'm Python {}", user, version);
Ok(())
})
}
本指南有一个关于此主题的示例部分。
工具和库
- maturin 使用 pyo3、rust-cpython 或 cffi 绑定以及 rust 二进制文件作为 Python 包构建和发布 crates
- setuptools-rust 支持 Rust 的 setuptools 插件。
- pyo3-built 简单宏,将使用
built
crate 获得的元数据作为PyDict
- rust-numpy NumPy C-API 的 Rust 绑定
- dict-derive 派生 FromPyObject,将 Python 字典自动转换为 Rust 结构体
- pyo3-log Rust 到 Python 日志的桥梁
- pythonize 将 Rust 对象转换为与 JSON 兼容的 Python 对象的 Serde 序列化器
- pyo3-asyncio 用于与 Python 的 Asyncio 库和异步函数一起工作的实用程序
- rustimport 直接从 Python 导入 Rust 文件或 crates,无需手动编译步骤。默认提供 pyo3 集成并自动生成 pyo3 绑定代码。
- pyo3-arrow pyo3 的轻量级 Apache Arrow 集成
示例
- autopy Python 和 Rust 的简单、跨平台的 GUI 自动化库。
- 包含在 TravisCI 和 AppVeyor 上构建轮子的示例,使用 cibuildwheel
- ballista-python 一个将 Apache Arrow 分布式查询引擎 Ballista 绑定的 Python 库。
- bed-reader 简单高效地读写 PLINK BED 格式。
- 展示了 Rayon/ndarray::parallel(包括错误捕获、控制线程数),Python 类型到 Rust 泛型的转换,GitHub Actions
- cryptography 具有一些 Rust 功能的 Python 加密库。
- css-inline 在 Rust 中实现的用于 Python 的 CSS 内联。
- datafusion-python 一个将 Apache Arrow 内存查询引擎 DataFusion 绑定的 Python 库。
- deltalake-python 基于 delta-rs 的原生 Delta Lake Python 绑定,具有 Pandas 集成。
- fastbloom 由 Rust 实现,用于 Rust 和 Python 的高效 bloom 过滤器 | 计数 bloom 过滤器。
- fastuuid Rust 的 UUID 库的 Python 绑定。
- feos 使用完全开发的 Python 接口的 Rust 中闪电般的物理解模。
- forust 一个用 Rust 编写的轻量级梯度提升决策树库。
- granian 适用于 Python 应用程序的 Rust HTTP 服务器。
- greptimedb 数据库支持 Python 脚本
- haem 用于生物信息学问题的 Python 库。
- html-py-ever 通过 html5ever 和 kuchiki 使用来加速 HTML 解析和 CSS 选择。
- hyperjson 使用 Rust 的 serde-json 读取/写入 JSON 数据的 Python 模块,速度极快。
- inline-python 直接在 Rust 代码中嵌入 Python 代码。
- johnnycanencrypt 带有 Yubikey 支持的 OpenPGP 库。
- jsonschema-rs 快速 JSON Schema 验证库。
- mocpy 提供用于描述单位球上任何任意覆盖区域的数值结构的 Python 天文库。
- opendal 数据访问层,允许用户以统一的方式轻松高效地从各种存储服务中检索数据。
- orjson 快速的 Python JSON 库。
- ormsgpack 快速的 Python msgpack 库。
- point-process 作为 Python 库的高级 API 用于点过程。
- polaroid 使用 Rust 编写的 Python 的超快速且安全的图像处理库。
- polars Rust、Python、Node.js 中的快速多线程 DataFrame 库。
- pydantic-core pydantic 的核心验证逻辑,用 Rust 编写。
- pyheck 快速大小写转换库,通过封装heck构建。
- 由于代码不多,所以很容易理解。
- pyre 使用Rust编写的快速Python HTTP服务器。
- pyreqwest_impersonate 最快的Python HTTP客户端,可以通过模拟头部和TLS/JA3/JA4/HTTP2指纹来模仿Web浏览器。
- ril-py 使用Rust编写的Python高性能高级图像处理库。
- river Python中的在线机器学习,计算量大的统计算法是用Rust实现的。
- rust-python-coverage PyO3项目的示例,具有Rust和Python的自动化测试覆盖率。
- tiktoken 用于与OpenAI的模型一起使用的快速BPE标记化器。
- tokenizers Hugging Face标记化器(NLP)的Python绑定,使用Rust编写。
- tzfpy 快速包,用于将经纬度转换为时区名称。
- utiles 快速的Python网络地图瓦片实用工具。
- wasmer-python 用于运行WebAssembly二进制的Python库。
文章和其他媒体
- (视频) 使用PyO3扩展Python - 2023年12月16日
- PyO3 + rust-numpy一周(如何将您的数据管道加速X倍) - 2023年6月6日
- (播客) PyO3与David Hewitt - 2023年5月19日
- 使用不到100行Rust让Python快100倍 - 2023年3月28日
- Pydantic V2如何利用Rust的超级功能 - 2023年2月4日
- 我们如何使用PyO3扩展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做出贡献!有许多方式可以支持这个项目,例如
- 在GitHub和Discord上帮助PyO3用户解决问题
- 改进文档
- 编写功能和错误修复
- 发布关于如何使用PyO3的博客和示例
我们的贡献笔记和架构指南提供了更多资源,如果您想为PyO3志愿服务并寻找起点。
如果您没有时间亲自贡献,但仍希望支持项目的未来成功,我们的一些维护者有GitHub赞助页面
许可协议
PyO3根据Apache-2.0许可协议或MIT许可协议进行许可,您可任选其一。
Python根据Python许可证进行许可。
除非您明确表示否则,根据Apache许可证定义,您有意提交给PyO3的任何贡献,都应按照上述方式双重许可,不附加任何额外条款或条件。
依赖项
~0.2–1.8MB
~32K SLoC