简体   繁体   English

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

[英]How to implement trait FromPyObject for my rust struct

Consider a simple rust class exposed via pyo3 to python考虑一个通过 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 {
        // ...
      }
    });
  }
}

now there is a function which should be called with two of this structs from python in that manner:现在有一个函数应该以这种方式使用 python 中的两个结构调用:

a = MyStruct()
b = MyStruct()

c = foo(a,b)

Therefore one defines因此一个定义

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

Now the compiler claims PyMyStruct should implement the trait FromPyObject :现在编译器声称PyMyStruct应该实现 trait FromPyObject

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

But I dont know how to retrieve an instance, pointer or whatever of PyMyStruct from PyAny ... Can someone help me?但我不知道如何从PyAny检索PyMyStruct的实例、指针或任何东西......有人可以帮助我吗?

I don't know much about this crate but I think that you should take your objects by reference.我对这个板条箱了解不多,但我认为你应该参考你的对象。 Note that they are shared with the rest of the Python interpreter, so you can't actually own them.请注意,它们与 Python 解释器的其余部分共享,因此您实际上无法拥有它们。

That is, just write:也就是说,只需写:

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

Or if you want mutable objects:或者,如果您想要可变对象:

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

This works because there are these impls :这是有效的,因为有这些 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>,

and then this other one :然后是另一个

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

What happens if you use the &mut variant and you pass the same object twice to this function?如果您使用&mut变体并将同一个对象传递给该函数两次,会发生什么情况? Well, I'm not sure but skimming the code I guess that you get two &mut references to the same object, and thus undefined behavior .好吧,我不确定但略读代码我猜你得到了两个&mut对同一个对象的引用,因此未定义的行为 If I were you, I'd use the non mut variant and use a RefCell if you actually want to change the object.如果我是你,我会使用非mut变体,如果你真的想改变对象,我会使用RefCell

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM