|
|
Boundは、pyo3 0.21で導入された構造体。
関数の引数としてPythonオブジェクトを受け取る場合は、従来のPy<T>よりBound<T>の方が良いらしい。
(Py<T>はポインターのようなものらしい)
use pyo3::prelude::*;
#[pymodule]
mod example_pyo3 {
use pyo3::{prelude::*, types::*};
#[pyfunction]
fn my_function(arg1: &Bound<PyString>) -> PyResult<String> {
let value: &str = arg1.extract()?;
let result = format!("Hello, {}", value);
Ok(result)
}
}
Boundを引数で使う場合、&Bound<>でもBound<>でもいいようだ。
Bound<T>からTのデータ型に変換するには、extractメソッドを使う。
例えばPyStringからは、&strやStringに変換することが出来る。
Bound<PyAny>から、Pythonの型を取得することが出来る。[2026-01-20]
#[pyfunction]
fn type_check(arg: &Bound<PyAny>) -> PyResult<()> {
let py_type = arg.get_type(); // Bound<PyType>
let type_name = py_type.name()?; // Bound<PyString>
println!("type_name: {}", type_name);
Ok(())
}
例えば、整数はint、浮動小数点はfloat、文字列はstr。
従来のPy<T>からBound<T>に変換するにはbindまたはinto_pyobjectメソッドを使う。[/2025-12-16]
use pyo3::prelude::*;
#[pymodule]
mod example_pyo3 {
use pyo3::{prelude::*, types::*};
#[pyfunction]
fn my_function2(py: Python, arg1: Py<PyString>) -> PyResult<String> {
let arg1 = arg1.bind(py); // &Bound<PyString>
// let arg1 = arg1.into_pyobject(py)?; // Bound<PyString>
let value: &str = arg1.extract()?;
let result = format!("Hello, {}", value);
Ok(result)
}
}
bindやinto_pyobjectメソッドの引数にはpyが必要なので、関数の第1引数に「py: Python」を追加しておく必要がある。
Bound<T>からPy<T>へ変換するにはunbindメソッドを使う。
use pyo3::prelude::*;
#[pymodule]
mod example_pyo3 {
use pyo3::{prelude::*, types::*};
#[pyfunction]
fn my_function3(py: Python, arg1: &str) -> PyResult<Py<PyString>> {
let result = format!("Hello, {}", arg1);
let bound_py_string = result.into_pyobject(py)?; // Bound<PyString>
let py_py_string = bound_py_string.unbind(); // Py<PyString>
Ok(py_py_string)
}
}
StringからPyStringに変換するにもinto_pyobjectメソッドを使う。
Bound<T>からPy<T>へ変換するにはintoメソッドを使うことも出来る。
#[pyfunction]
fn my_function4(py: Python, arg1: &str) -> PyResult<Py<PyString>> {
let result = format!("Hello, {}", arg1);
let bound_py_string = result.into_pyobject(py)?; // Bound<PyString>
Ok(bound_py_string.into())
}
Bound<T>を返す場合は、ライフタイムを明示する。[2026-02-04]
#[pyfunction]
fn my_function5<'py>(py: Python<'py>, arg1: &str) -> PyResult<Bound<'py, PyString>> {
let result = format!("Hello, {}", arg1);
let bound_py_string = result.into_pyobject(py)?; // Bound<PyString>
Ok(bound_py_string)
}
Boundの定義は、厳密にはBound<'py, T>である。(使用方法によってはライフタイム'pyを省略できる)
Bound<T>のインスタンスを生成する場合、py: Pythonが使われる。
Pythonもライフタイムを持っており、厳密にはPython<'py>である。
Boundのライフタイム(生存期間)はPythonのライフタイム以下なので、 メソッドや関数の返り値の型として使う場合はPythonと同じライフタイムを指定する。