【问题标题】:Using pyo3 pyclass on a rust struct that contains types from a different crate在包含来自不同 crate 的类型的 rust 结构上使用 pyo3 pyclass
【发布时间】:2020-12-21 13:01:07
【问题描述】:

我有一个 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 geo 库中的 Point 类型。编译器提供以下错误: the trait `pyo3::PyClass` is not implemented for `geo::Point&lt;f64&gt;

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

impl PyClass for Point<f64> {}

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

关于解决此问题的简洁方法有什么想法吗?

【问题讨论】:

  • 仅供参考,上面的代码现在可以编译

标签: python rust pyo3


【解决方案1】:

在找到更好的答案之前,我的解决方案是将类嵌套在 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)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多