Привязки Rust для Python, включая инструменты для создания собственных модулей расширения Python. Также поддерживается запуск и взаимодействие с кодом Python из двоичного файла Rust.
Руководство пользователя: стабильная | основной
Документация API: стабильная | основной
Требуется Rust 1.63 или выше.
PyO3 поддерживает следующие дистрибутивы Python:
Вы можете использовать PyO3 для написания собственного модуля Python на Rust или для встраивания Python в двоичный файл Rust. В следующих разделах поочередно описывается каждый из них.
PyO3 можно использовать для создания собственного модуля Python. Самый простой способ попробовать это впервые — использовать maturin
. maturin
— это инструмент для создания и публикации пакетов Python на основе Rust с минимальной настройкой. Следующие шаги устанавливают maturin
, используют его для создания и сборки нового пакета Python, а затем запускают Python для импорта и выполнения функции из пакета.
Сначала следуйте командам ниже, чтобы создать новый каталог, содержащий новую virtualenv
Python, и установите maturin
в виртуальную среду с помощью менеджера пакетов Python pip
:
# (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. После этого пакет готов к использованию из 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
, но для начала работы требуется больше настроек.
Чтобы встроить Python в двоичный файл Rust, вам необходимо убедиться, что ваша установка Python содержит общую библиотеку. Следующие шаги демонстрируют, как это обеспечить (для Ubuntu), а затем приводят пример кода, который запускает встроенный интерпретатор Python.
Чтобы установить общую библиотеку Python в Ubuntu:
sudo apt install python3-dev
Чтобы установить общую библиотеку Python в дистрибутивах на основе RPM (например, Fedora, Red Hat, SuSE), установите пакет 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, должен иметь двойную лицензию, как указано выше, без каких-либо дополнительных положений и условий.