如何将PyO3中#[pyclass]派生的Rust结构体实例转为PyObject?
将PyO3的#[pyclass]结构体实例转换为PyObject
对于你这种继承了Python内置类型(这里是PyTypeError)的#[pyclass]结构体,直接调用不存在的into_pyobject方法是行不通的。正确的做法是通过Py::new来创建包含你的Rust结构体实例的Python对象——带extends的类是作为基类对象的扩展存在的,必须和基类实例绑定后才能成为有效的Python对象。
修改你的代码如下:
use pyo3::exceptions::PyTypeError; use pyo3::prelude::*; #[pyclass(extends=PyTypeError)] pub struct Foo { bar: PyObject, baz: PyObject, } impl Foo { fn fun(self, py: Python) -> PyResult<PyObject> { // 1. 创建基类PyTypeError的实例 let base = PyTypeError::new_err("自定义错误信息"); // 2. 创建包含Foo实例和基类实例的Python对象 let py_foo = Py::new(py, (self, base))?; // 3. 将Py<Foo>转换为PyObject Ok(py_foo.into()) } }
关键说明:
- 因为
Foo继承了PyTypeError,创建Python对象时需要传入元组(self, base),其中base是基类的实例 Py::new会自动处理GIL持有和垃圾回收注册逻辑,返回的Py<Foo>是安全的Python对象引用- 通过
Intotrait,Py<T>可以直接转换为PyObject,无需额外方法调用 - 方法返回值改为
PyResult<PyObject>,因为创建Python对象可能失败(如内存不足),需要处理错误
内容的提问来源于stack exchange,提问作者drhagen
相关产品推荐
相关产品推荐

