[OSS紹介#20] PyO3:RustとPythonを結ぶ架け橋、効率的な開発を実現するツール

この記事について

この記事では、注目のオープンソースソフトウェア(OSS)「PyO3」を紹介します。このシリーズでは、開発者が注目すべきツールやライブラリを定期的にお届けしていますが、第20回目となる今回は、前回取り上げた「pytauri」につながる重要な資源について焦点を当てます。

「PyO3」は、Rustとの相互運用性を持つPython拡張モジュールを簡単に作成できるツールで、PythonとRustの強みを組み合わせて、より効率的な子プログラムやライブラリの開発を可能にします。特に、Rustの安全性やパフォーマンスを活かしながら、Pythonの利便性を享受できるという利点があります。

近年、プログラミングにおいては言語の選択肢が多様化しており、それに伴い異なる言語間の連携が重要な課題となっています。このような背景の中で「PyO3」は、PythonユーザーがRustを利用するための効果的な手段を提供し、今後の開発の流れに影響を与える可能性を秘めています。本記事では、「PyO3」の基本機能や利用方法、さらには実際の活用例について詳しく見ていきます。

リンク:https://github.com/PyO3/pyo3


本コンテンツは、弊社AI開発ツール「IXV」を用いたOSSツール紹介です。情報の正確性には努めておりますが、内容に誤りが含まれる可能性がございますのでご了承ください。

1. PyO3でできること

PyO3は、RustとPythonの間のバインディングを提供するライブラリです。これにより、Rustで書かれたコードをPythonから呼び出したり、逆にPythonをRustプロジェクトに埋め込むことが可能です。具体的には、以下のような機能を提供します。

  • ネイティブ Python モジュールの作成: PyO3 を使うことで、Rust で書かれた関数を Python から呼び出すことができます。
  • Python の埋め込み: Rust アプリケーションに Python インタプリタを組み込むことができ、Python コードを直接実行できます。
  • 多様な Python ディストリビューションのサポート: CPython 3.7 以上、PyPy 7.3、GraalPy 24.0 以上に対応しています。

2. セットアップ手順

2.1 必要な環境

PyO3を利用するには、以下の環境が必要です。
– Rust 1.63以上
– CPython 3.7以上またはPyPy 7.3以上またはGraalPy 24.0以上

2.2 ツールのインストール

PyO3 を利用するためには、`maturin`というツールを使用することが推奨されています。以下の手順で新しいディレクトリを作成し、仮想環境を設定します。

mkdir string_sum
cd string_sum
python -m venv .env
source .env/bin/activate
pip install maturin

2.3 プロジェクトの初期化

次に、`maturin init`を実行してプロジェクトを初期化します。

maturin init

このコマンドにより、`Cargo.toml`と`lib.rs`が生成されます。`Cargo.toml`には、以下のように依存関係が設定されます。

[dependencies]
pyo3 = { version = "0.24.2", features = ["extension-module"] }

2.4 ビルドとインストール

プロジェクトのセットアップが完了したら、次のコマンドでビルドとインストールを行います。

$ maturin develop

これにより、生成されたパッケージが Python の仮想環境にインストールされ、Python から Rust の関数を呼び出すことができるようになります。

3. 簡単な使い方

3.1 RustからPythonを呼び出す例

以下は、RustからPythonのsysモジュールを呼び出してバージョンを取得する例です。

use pyo3::prelude::*;

fn main() -> PyResult<()> {
    Python::with_gil(|py| {
        let sys = py.import("sys")?;
        let version: String = sys.getattr("version")?.extract()?;
        println!("Python version: {}", version);
        Ok(())
    })
}

3.2 PythonでRustモジュールを使用する例

Rustで作成したモジュールをPythonから使用する例を見てみましょう。maturinを使って生成したプロジェクトを例に説明します。

まず、前述の手順でプロジェクトを作成した後、src/lib.rsに次のようなRustコードが生成されています:

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.
#[pymodule]
fn string_sum(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
    Ok(())
}

maturin developでビルドしたら、以下のようにPythonから使用できます:

import string_sum

result = string_sum.sum_as_string(5, 20)print(result) # 返り値は'25'

このように、Rustで実装した関数を直接Pythonから呼び出すことができます。Pythonのコードからは、通常のPythonモジュールと同じように使用でき、内部がRustで実装されていることを意識する必要はありません。

4. 結論

PyO3は、RustとPythonの間でのスムーズなインターフェースを提供する強力なツールです。Rustの性能を活かしつつ、Pythonの柔軟性を享受できるため、両方の言語の利点を最大限に活かした開発が可能になります。PyO3を使用することで、ネイティブなPythonモジュールの作成や、RustアプリケーションへのPythonの埋め込みが簡単になり、さらなるプロジェクトの発展が期待できます。興味のある方は、ぜひ公式ドキュメントを参照し、手を動かしてみてください。