官方readme
下面有任何有疑问的接口中的名称都直接去api文档中搜索
在Python中使用Rust
PyO3用来生成原生 Python 模块,最简单的方法是使用maturin
,这是一个用最少配置发布基于 Rust 的 Python 包的工具。新建一个测试用的文件夹
# (replace string_sum with the desired package name)
$ mkdir string_sum
$ cd string_sum
$ pip install maturin
在上述string_sum
文件夹中初始化maturin
,
$ maturin init
✔ 🤷 What kind of bindings to use? · pyo3
✨ Done! New project created string_sum
可以看到生成了新包的source,最重要的文件时Cargo.toml
和lib.rs
,大约文件中看起来是这样的
Cargo.toml
[package]
name = "string_sum"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[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.18.1"
src/lib.rs
#![allow(unused)] fn main() { 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(_py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(sum_as_string, m)?)?; Ok(()) } }
最后,终端输入maturin develop
。这会创建一个 package 然后安装进当前的 Python 环境,然后这个 package 就能在 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中使用Python
将 Python 嵌入为 Rust 二进制,你要确保你的 Python 安装包含了一个共享库(ensure that your Python installation contains a shared library?啥意思)。
用 cargo new
新建一个项目并像这样将 pyo3
加入到 Cargo.toml
中,
[dependencies.pyo3]
version = "0.18.1"
features = ["auto-initialize"]
下面的例子会输出 sys.version
的值以及当前用户名
use pyo3::prelude::*; use pyo3::types::IntoPyDict; fn main() -> PyResult<()> { Python::with_gil(|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 = "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(()) }) }
如果
cargo run
后出现Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
,上面信息中应该还有PYTHONHOME: not set, PYTHONPATH: not set
的信息,应该将使用的 Python 解释器路径加入到系统环境中,比如 Annconda 则将 Annaconda 文件夹路径创建为PYTHONHOME
,其下的 python.exe 路径创建为PYTHONPATH
。
工具和库
- maturin Build and publish crates with pyo3, rust-cpython or cffi bindings as well as rust binaries as python packages
- setuptools-rust Setuptools plugin for Rust support.
- pyo3-built Simple macro to expose metadata obtained with the
built
crate as aPyDict
- rust-numpy Rust binding of NumPy C-API
- dict-derive Derive FromPyObject to automatically transform Python dicts into Rust structs
- pyo3-log Bridge from Rust to Python logging
- pythonize Serde serializer for converting Rust objects to JSON-compatible Python objects
- pyo3-asyncio Utilities for working with Python's Asyncio library and async functions
- rustimport Directly import Rust files or crates from Python, without manual compilation step. Provides pyo3 integration by default and generates pyo3 binding code automatically.
例子
- autopy A simple, cross-platform GUI automation library for Python and Rust.
- Contains an example of building wheels on TravisCI and appveyor using cibuildwheel
- ballista-python A Python library that binds to Apache Arrow distributed query engine Ballista.
- bed-reader Read and write the PLINK BED format, simply and efficiently.
- Shows Rayon/ndarray::parallel (including capturing errors, controlling thread num), Python types to Rust generics, Github Actions
- cryptography Python cryptography library with some functionality in Rust.
- css-inline CSS inlining for Python implemented in Rust.
- datafusion-python A Python library that binds to Apache Arrow in-memory query engine DataFusion.
- deltalake-python Native Delta Lake Python binding based on delta-rs with Pandas integration.
- fastbloom A fast bloom filter | counting bloom filter implemented by Rust for Rust and Python!
- fastuuid Python bindings to Rust's UUID library.
- feos Lightning fast thermodynamic modeling in Rust with fully developed Python interface.
- forust A lightweight gradient boosted decision tree library written in Rust.
- html-py-ever Using html5ever through kuchiki to speed up html parsing and css-selecting.
- hyperjson A hyper-fast Python module for reading/writing JSON data using Rust's serde-json.
- inline-python Inline Python code directly in your Rust code.
- jsonschema-rs Fast JSON Schema validation library.
- mocpy Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere.
- orjson Fast Python JSON library.
- ormsgpack Fast Python msgpack library.
- point-process High level API for pointprocesses as a Python library.
- polaroid Hyper Fast and safe image manipulation library for Python written in Rust.
- polars Fast multi-threaded DataFrame library in Rust | Python | Node.js.
- pydantic-core Core validation logic for pydantic written in Rust.
- pyheck Fast case conversion library, built by wrapping heck.
- Quite easy to follow as there's not much code.
- pyre Fast Python HTTP server written in Rust.
- ril-py A performant and high-level image processing library for Python written in Rust.
- river Online machine learning in python, the computationally heavy statistics algorithms are implemented in Rust.
- rust-python-coverage Example PyO3 project with automated test coverage for Rust and Python.
- tiktoken A fast BPE tokeniser for use with OpenAI's models.
- tokenizers Python bindings to the Hugging Face tokenizers (NLP) written in Rust.
- wasmer-python Python library to run WebAssembly binaries.
Articles and other media
- How Pydantic V2 leverages Rust's Superpowers - Feb 4, 2023
- Nine Rules for Writing Python Extensions in Rust - Dec 31, 2021
- Calling Rust from Python using PyO3 - Nov 18, 2021
- davidhewitt's 2021 talk at Rust Manchester meetup - Aug 19, 2021
- Incrementally porting a small Python project to Rust - Apr 29, 2021
- Vortexa - Integrating Rust into Python - Apr 12, 2021
- Writing and publishing a Python module in Rust - Aug 2, 2020