Rust-Bindungen für Python, einschließlich Tools zum Erstellen nativer Python-Erweiterungsmodule. Das Ausführen und Interagieren mit Python-Code aus einer Rust-Binärdatei wird ebenfalls unterstützt.
Benutzerhandbuch: stabil | hauptsächlich
API-Dokumentation: stabil | hauptsächlich
Erfordert Rust 1.63 oder höher.
PyO3 unterstützt die folgenden Python-Distributionen:
Sie können PyO3 verwenden, um ein natives Python-Modul in Rust zu schreiben oder Python in eine Rust-Binärdatei einzubetten. In den folgenden Abschnitten werden diese nacheinander erläutert.
Mit PyO3 kann ein natives Python-Modul generiert werden. Der einfachste Weg, dies zum ersten Mal auszuprobieren, ist die Verwendung maturin
. maturin
ist ein Tool zum Erstellen und Veröffentlichen von Rust-basierten Python-Paketen mit minimaler Konfiguration. Mit den folgenden Schritten installieren Sie maturin
, generieren und erstellen damit ein neues Python-Paket und starten dann Python, um eine Funktion aus dem Paket zu importieren und auszuführen.
Befolgen Sie zunächst die folgenden Befehle, um ein neues Verzeichnis mit einer neuen Python- virtualenv
zu erstellen, und installieren Sie maturin
mithilfe des Python-Paketmanagers pip
in der 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
Immer noch in diesem string_sum
-Verzeichnis, führen Sie jetzt maturin init
aus. Dadurch wird die neue Paketquelle generiert. Wenn Sie die Wahl zwischen den zu verwendenden Bindungen haben, wählen Sie pyo3-Bindungen aus:
$ maturin init
✔ ? What kind of bindings to use ? · pyo3
Done ! New project created string_sum
Die wichtigsten von diesem Befehl generierten Dateien sind Cargo.toml
und lib.rs
, die ungefähr wie folgt aussehen:
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 ( ( ) )
}
Zum Schluss führen Sie maturin develop
aus. Dadurch wird das Paket erstellt und in der zuvor erstellten und aktivierten Python-Virtualenv installiert. Das Paket kann dann von python
aus verwendet werden:
$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
' 25 '
Um Änderungen am Paket vorzunehmen, bearbeiten Sie einfach den Rust-Quellcode und führen Sie dann maturin develop
erneut aus, um es neu zu kompilieren.
Um dies alles als einmaliges Kopieren und Einfügen auszuführen, verwenden Sie das folgende Bash-Skript (ersetzen Sie string_sum
im ersten Befehl durch den gewünschten Paketnamen):
mkdir string_sum && cd " $_ "
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop
Wenn Sie cargo test
ausführen oder dieses Projekt in einem Cargo-Arbeitsbereich verwenden möchten und auf Linker-Probleme stoßen, finden Sie in den FAQ einige Problemumgehungen.
Neben maturin
ist es auch möglich, mit setuptools-rust
oder manuell zu erstellen. Beide bieten mehr Flexibilität als maturin
, erfordern jedoch für den Einstieg mehr Konfiguration.
Um Python in eine Rust-Binärdatei einzubetten, müssen Sie sicherstellen, dass Ihre Python-Installation eine gemeinsam genutzte Bibliothek enthält. Die folgenden Schritte zeigen, wie dies sichergestellt wird (für Ubuntu), und geben dann einen Beispielcode an, der einen eingebetteten Python-Interpreter ausführt.
So installieren Sie die gemeinsam genutzte Python-Bibliothek unter Ubuntu:
sudo apt install python3-dev
Um die gemeinsam genutzte Python-Bibliothek auf RPM-basierten Distributionen (z. B. Fedora, Red Hat, SuSE) zu installieren, installieren Sie das Paket python3-devel
.
Starten Sie ein neues Projekt mit cargo new
und fügen Sie pyo3
wie folgt zur Cargo.toml
hinzu:
[ dependencies . pyo3 ]
version = " 0.23.3 "
features = [ " auto-initialize " ]
Beispielprogramm, das den Wert von sys.version
und den aktuellen Benutzernamen anzeigt:
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 ( ( ) )
} )
}
Der Leitfaden enthält einen Abschnitt mit vielen Beispielen zu diesem Thema.
built
Kiste erhalten wurden, als PyDict
Jeder ist herzlich willkommen, einen Beitrag zu PyO3 zu leisten! Es gibt viele Möglichkeiten, das Projekt zu unterstützen, wie zum Beispiel:
Unsere Beitragsnotizen und der Architekturleitfaden bieten weitere Ressourcen, wenn Sie ehrenamtlich Zeit für PyO3 aufwenden möchten und suchen, wo Sie anfangen sollen.
Wenn Sie keine Zeit haben, selbst einen Beitrag zu leisten, aber dennoch den zukünftigen Erfolg des Projekts unterstützen möchten, haben einige unserer Betreuer GitHub-Sponsorseiten:
PyO3 ist nach Ihrer Wahl unter der Apache-2.0-Lizenz oder der MIT-Lizenz lizenziert.
Python ist unter der Python-Lizenz lizenziert.
Sofern Sie nicht ausdrücklich etwas anderes angeben, unterliegt jeder von Ihnen absichtlich zur Aufnahme in PyO3 eingereichte Beitrag gemäß der Definition in der Apache-Lizenz einer Doppellizenz wie oben, ohne zusätzliche Bedingungen oder Konditionen.