S-JIS[2025-12-13]

pyo3 クラス定義

Rustpyo3でクラスを定義する方法のメモ。


概要

Pythonでクラスとして扱うものをPyO3 0.27で定義するには、structに#[pyclass]を付け、implに#[pymethods]を付ける。


Rust側でMyClassを定義する。

example-pyo3/src/lib.rs:

use pyo3::prelude::*;

#[pymodule]
mod example_pyo3 {
    use pyo3::{prelude::*};

    #[pyclass]
    struct MyClass {
        #[pyo3(get, set)]
        value: String,
    }

    #[pymethods]
    impl MyClass {
        #[new]
        fn new(value: String) -> Self {
            Self { value }
        }

        #[getter]
        fn my_value(&self) -> &str {
            &self.value
        }

        fn my_method(&self) -> &str {
            &self.value
        }
    }

    #[pyfunction]
    fn create_my_class(value: String) -> MyClass {
        MyClass { value }
    }
}

呼び出すPython側

call-pyo3/main.py:

import example_pyo3

def main():
    print("Hello from call-pyo3!")

    c = example_pyo3.create_my_class("abc") // MyClassインスタンスを返す関数の呼び出し
    print(c.value)
    print(c.my_value)
    print(c.my_method())

    m = example_pyo3.MyClass("zzz") // MyClassコンストラクターの呼び出し
    print(m.value)
    print(m.my_value)
    print(m.my_method())
    m.value = "def"
    print(m.value)
    print(m.my_value)
    print(m.my_method())

if __name__ == "__main__":
    main()

属性

#[pyclass] struct

    #[pyclass]
    struct MyClass {
        #[pyo3(get, set)]
        value: String,
    }
属性 説明 Rustの実装例 Pythonの使用例
#[pyo3(get)] プロパティーとして値を取得できる。 #[pyo3(get)]
value: String,
v = obj.value
#[pyo3(set)] プロパティーとして値を設定できる。 #[pyo3(set)]
value: String,
obj.value = "abc"

#[pymethods] impl

    #[pymethods]
    impl MyClass {
〜
    }
属性 説明 Rustの実装例 Pythonの使用例
#[new] コンストラクターとして扱われる。 #[new]
fn new(value: String) -> Self {
    Self { value }
}
obj = example_pyo3.MyClass("abc")
なし 何も属性を付けないfnは、メソッドとして呼び出せる。 fn my_method(&self) -> &str {
    &self.value
}
v = obj.my_method()
#[getter] プロパティーとして値を取得する。
メソッド名の先頭の「get_」を除いた部分がプロパティー名になる。
メソッド名の先頭が「get_」でない場合はメソッド名がそのままプロパティー名になる。
#[getter]
fn get_my_value(&self) -> &str {
    &self.value
}
v = obj.my_value
#[getter]
fn my_value(&self) -> &str {
    &self.value
}
#[setter] プロパティーとして値を設定する。
メソッド名の先頭の「set_」を除いた部分がプロパティー名になる。
#[setter]
fn set_my_value(&mut self, value: String) {
    self.value = value;
}
obj.my_value = "abc"

構造体のソースファイルを分ける例

構造体を別のソースファイルで定義し、pymoduleに取り込むことが出来る。

example-pyo3/src/my_class.rs

use pyo3::prelude::*;

#[pyclass]
pub struct MyClass {
    value: String,
}

#[pymethods]
impl MyClass {
    #[new]
    fn new(value: String) -> Self {
        Self { value }
    }

    fn my_method(&self) -> &str {
        &self.value
    }
}

example-pyo3/src/lib.rs:

use pyo3::prelude::*;

mod my_class;

#[pymodule]
mod example_pyo3 {
    use pyo3::prelude::*;

    #[pymodule_export]
    use super::my_class::MyClass;
}

#[pymodule_export]で、他の場所で定義されている構造体をPyhton用にエクスポートする。

call-pyo3/main.py:

import example_pyo3

def main():
    c = example_pyo3.MyClass("abc")
    print(c.my_method())

if __name__ == "__main__":
    main()

pyo3へ戻る / Rustへ戻る / 技術メモへ戻る
メールの送信先:ひしだま