微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在包含来自不同板条箱的类型的 rust 结构上使用 pyo3 pyclass

如何解决在包含来自不同板条箱的类型的 rust 结构上使用 pyo3 pyclass

我有一个 rust 结构,它使用 pyo3 pyclass 宏来允许在 python 中使用。这适用于简单的结构,但如果我有一个包含来自不同库的类型的结构,它会变得更加困难。

示例:

use geo::Point;

#[pyclass]
#[derive(Clone,copy)]
pub struct CellState {
    pub id: u32,pub position: Point<f64>,pub population: u32,}

上面我们使用 Rust 地理库中的 Point 类型。编译器提供以下错误the trait `pyo3::PyClass` is not implemented for `geo::Point<f64>

如果我尝试在 Point 上实现 PyClass:

impl PyClass for Point<f64> {}

它给了我以下编译器错误impl doesn't use only types from inside the current crate

是否有任何解决此问题的简洁方法的想法?

解决方法

在出现更好的答案之前,我的解决方案是将类嵌套在 python 类中,但随后我不得不手动编写 getter 和 setter。

#[pyclass]
#[derive(Clone)]
pub struct CellStatePy {
    pub inner: CellState,}

#[pymethods]
impl CellStatePy {
    #[new]
    pub fn new(id: u32,pos: (f64,f64),population: u32) -> Self {
        CellStatePy {
            inner: CellState {
                id: CellIndex(id),position: point!(x: pos.0,y: pos.1),population,},}
    }
}

然后实现PyObjectProtocol:

#[pyproto]
impl PyObjectProtocol for CellStatePy {
    fn __str__(&self) -> PyResult<&'static str> {
        Ok("CellStatePy")
    }

    fn __repr__<'a>(&'a self) -> PyResult<String> {
        Ok(format!("CellStateObj id: {:?}",self.inner.id))
    }

    fn __getattr__(&'a self,name: &str) -> PyResult<String> {
        let out: String = match name {
            "id" => self.inner.id.into(),"position" => format!("{},{}",self.inner.position.x(),self.inner.position.y()),"population" => format!("{}",self.inner.population),&_ => "INVALID FIELD".to_owned(),};
        Ok(out)
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。