Python 的 Rust 綁定,包括用於建立本機 Python 擴充模組的工具。也支援從 Rust 二進位檔案運行 Python 程式碼並與之互動。
使用者指南:穩定|主要的
API 文件:穩定 |主要的
需要 Rust 1.63 或更高版本。
PyO3 支援以下 Python 發行版:
您可以使用 PyO3 在 Rust 中編寫本機 Python 模組,或將 Python 嵌入 Rust 二進位檔案中。以下部分依序解釋其中的每一個。
PyO3 可用於生成本機 Python 模組。第一次嘗試最簡單的方法是使用maturin
。 maturin
是一個用最少的配置來建構和發布基於 Rust 的 Python 套件的工具。以下步驟安裝maturin
,使用它來產生和建立新的 Python 套件,然後啟動 Python 以匯入並執行套件中的函數。
首先,按照以下命令建立一個包含新 Python virtualenv
新目錄,並使用 Python 的套件管理器pip
將maturin
安裝到 virtualenv 中:
# (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.23.3 " , 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 virtualenv 中。然後就可以從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
或在貨物工作區中使用此項目並且遇到連結器問題,常見問題中提供了一些解決方法。
與maturin
一樣,可以使用setuptools-rust
或手動進行建置。兩者都比maturin
提供了更多的靈活性,但需要更多的配置才能開始。
要將 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.23.3 "
features = [ " auto-initialize " ]
顯示sys.version
值和目前使用者名稱的範例程式:
use pyo3 :: prelude :: * ;
use pyo3 :: types :: IntoPyDict ;
use pyo3 :: ffi :: c_str ;
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 = c_str ! ( "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 ( ( ) )
} )
}
該指南有一個部分包含許多有關該主題的範例。
built
板條箱所獲得的元資料公開為PyDict
歡迎大家為 PyO3 做出貢獻!支持該項目的方式有很多,例如:
如果您願意為 PyO3 貢獻時間並正在尋找從哪裡開始,我們的貢獻筆記和架構指南有更多資源。
如果您沒有時間做出貢獻,但仍希望支持專案未來的成功,我們的一些維護人員有 GitHub 贊助頁面:
PyO3 根據 Apache-2.0 許可證或 MIT 許可證獲得許可,具體由您選擇。
Python 根據 Python 許可證獲得許可。
除非您另有明確說明,否則您有意提交的包含在 PyO3 中的任何貢獻(如 Apache 許可證中所定義)應如上所述獲得雙重許可,沒有任何附加條款或條件。