如何为我的 rust 结构实现 trait FromPyObject
How to implement trait FromPyObject for my rust struct
考虑一个简单的铁锈 class 通过 pyo3 暴露到 python
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
的任何内容...
有人可以帮助我吗?
我对这个板条箱了解不多,但我认为您应该参考您的物品。请注意,它们与 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
。
考虑一个简单的铁锈 class 通过 pyo3 暴露到 python
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
的任何内容...
有人可以帮助我吗?
我对这个板条箱了解不多,但我认为您应该参考您的物品。请注意,它们与 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
。