在包含来自不同板条箱的类型的 Rust 结构上使用 pyo3 pyclass
Using pyo3 pyclass on a rust struct that contains types from a different crate
我有一个使用 pyo3 pyclass 宏的 rust 结构,允许在 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<f64>
如果我然后尝试在点上实现 PyClass:
impl PyClass for Point<f64> {}
它给我以下编译器错误:
impl doesn't use only types from inside the current crate
关于解决此问题的简洁方法有什么想法吗?
在出现更好的答案之前,我的解决方案是将 class 嵌套在 python class 中,但我不得不手动编写 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)
}
}
我有一个使用 pyo3 pyclass 宏的 rust 结构,允许在 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<f64>
如果我然后尝试在点上实现 PyClass:
impl PyClass for Point<f64> {}
它给我以下编译器错误:
impl doesn't use only types from inside the current crate
关于解决此问题的简洁方法有什么想法吗?
在出现更好的答案之前,我的解决方案是将 class 嵌套在 python class 中,但我不得不手动编写 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)
}
}