如何在Rust中从PyAny实例属性提取#[pyclass]结构体实例?
从Python类实例中提取Rust结构体实例的实现方法
要实现从MyPythonClass实例(类型为PyAny)中提取MyRustClass结构体实例,可借助PyO3提供的属性获取与类型转换API完成,具体实现如下:
完整代码示例
use pyo3::prelude::*; #[pyclass] struct MyRustClass { foo: i32 } #[pymethods] impl MyRustClass { #[new] fn new(foo: i32) -> Self { MyRustClass { foo } } // 可选:若字段非pub,需添加getter方法访问内部数据 #[getter] fn get_foo(&self) -> i32 { self.foo } } #[pyfunction] fn my_cool_function(python_class: PyAny) -> PyResult<()> { // 1. 从Python实例中获取my_rust_class属性 let rust_attr = python_class.getattr("my_rust_class")?; // 2. 将属性转换为MyRustClass的引用(或Py<MyRustClass>获取所有权) let rust_instance = rust_attr.extract::<&MyRustClass>()?; // 3. 操作Rust结构体实例 // 若字段为pub,直接访问:println!("Foo value: {}", rust_instance.foo); // 若字段非pub,调用getter方法: println!("Foo value: {}", rust_instance.get_foo()); Ok(()) } // 注册结构体与函数到Python模块 #[pymodule] fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::<MyRustClass>()?; m.add_function(wrap_pyfunction!(my_cool_function, m)?)?; Ok(()) }
关键逻辑说明
- 获取属性:调用
PyAny::getattr("my_rust_class")获取Python实例的指定属性,返回PyResult<PyAny>,用?处理属性不存在等异常。 - 类型转换:通过
extract::<&MyRustClass>()将PyAny类型的属性转换为MyRustClass的引用;若需获取实例所有权,可改为extract::<Py<MyRustClass>>()。 - 访问内部数据:若
MyRustClass的字段是pub修饰的,可直接访问;若字段私有,需在#[pymethods]中定义getter方法来获取数据。
内容的提问来源于stack exchange,提问作者Darren
相关产品推荐
相关产品推荐

