rust - 如何为我的 rust 结构实现 trait FromPyObject

标签 rust pyo3

考虑一个通过 pyo3 暴露给 python 的简单 rust 类

use pyo3::prelude::*;

#[pyclass(name=MyClass)]
pub struct PyMyClass {
  // Some fields
}

#[pymethods]
impl PyMyStruct {
  #[new]
  fn py_new(obj: PyRawObject) {
    obj.init({
      PyMyStruct {
        // ...
      }
    });
  }
}

现在有一个函数应该以这种方式用 python 中的两个结构调用:

a = MyStruct()
b = MyStruct()

c = foo(a,b)

因此定义

#[pyfunction]
fn foo(a: PyMyStruct, b: PyMyStruct) -> PyResult<PyMyStruct> {
  // some high performance logic implemented in rust ...
}

现在编译器声称 PyMyStruct 应该实现特征 FromPyObject:

impl FromPyObject<'_> for PyMyStruct {
    fn extract(ob: &'_ PyAny) ->PyResult<Self> {
        // I dont know what to do here :(
    }
}

但我不知道如何从 PyAny 中检索实例、指针或任何 PyMyStruct... 有人可以帮助我吗?

最佳答案

我对这个 crate 了解不多,但我认为您应该引用您的元素。请注意,它们与 Python 解释器的其余部分共享,因此您不能真正拥有它们。

也就是只写:

#[pyfunction]
fn foo(a: &PyMyStruct, b: &PyMyStruct) -> PyResult<PyMyStruct> {
  // some high performance logic implemented in rust ...
}

或者如果你想要可变对象:

#[pyfunction]
fn foo(a: &mut PyMyStruct, b: &mut PyMyStruct) -> PyResult<PyMyStruct> {
  // some high performance logic implemented in rust ...
}

之所以可行,是因为有 these impls :

impl<'a, T> FromPyObject<'a> for &'a T where
    T: PyTryFrom<'a>
impl<'a, T> FromPyObject<'a> for &'a mut T where
    T: PyTryFrom<'a>,

然后这个other one :

impl<'v, T> PyTryFrom<'v> for T where
    T: PyTypeInfo

如果您使用 &mut 变体并将同一个对象传递给此函数两次,会发生什么情况?好吧,我不确定,但浏览代码我猜你会得到对同一个对象的两个 &mut 引用,因此未定义的行为。如果我是你,我会使用非 mut 变体,如果你真的想更改对象,我会使用 RefCell

关于rust - 如何为我的 rust 结构实现 trait FromPyObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57132033/

相关文章:

rust - dotenv()。ok()有什么作用?

python - 返回对 PyO3 中成员字段的引用

python - 如何使用 pyo3 从 Python 文件中调用 Rust 函数?

python - 如何通过 Rust PyO3 从 Whisper transcribe python API 中提取文本

rust - 如何用未装箱的闭包替换 proc?

rust - 通过函数参数传入并使用Type?

rust - native 库 `kernel32` 被多个包链接

rust - 如何删除Rust中另一个矢量中出现的矢量元素?

python - PyO3 中对象向量的垃圾收集

python - 如何使用 PyO3 解码 PyCodeObject?