6

我是 Rust 和 PyO3(来自 Python)的新手,所以这对于更有经验的人来说可能是显而易见的。

我在 PyO3 中声明了一个 pyclass 结构。

#[pyclass]
struct Block {
    start: i32,
    stop: i32,
}

然后我Block在一个 rust 函数中使用,它接受一个向量Block并输出一个 int 向量(下面的签名)

#[pyfunction]
fn from_blocks(block_list: Vec<Block>) -> Vec<i32>

当我使用编译时nightly-x86_64-apple-darwin,出现以下错误:

#[pyfunction]
^^^^^^^^^^^^^ the trait `pyo3::FromPyObject<'_>` is not implemented for `std::vec::Vec<Block>`

我该如何解决这个问题?

编辑: Caio 是对的。我在追溯错误时犯了一个错误。以前我写过

然后我在一个 rust 函数中使用 Block,该函数接受一个 int 向量并输出一个 Block 向量(下面的签名)

#[pyfunction]
fn to_blocks(list: Vec<i32>) -> Vec<Block>

但实际的违规功能是:

#[pyfunction]
fn from_blocks(block_list: Vec<Block>) -> Vec<i32>

我已经更新了问题以使其更清楚。

4

3 回答 3

5

FromPyObject旨在供可以从 Python 世界中提取的类型使用。这就是为什么我认为你试图写fn to_blocks(list: Vec<Block>) -> Vec<i32>而不是fn to_blocks(list: Vec<i32>) -> Vec<Block>. 如果是这样的话,让我们进入实现链。

FromPyObject对任何实现 PyTryFrom的&T都有一个默认实现,对任何实现 PyTypeInfo 的 TPyTryFrom都有一个默认实现。实现或根据方法,并且两个特征都具有特征绑定。因此,您的类/结构将与引用一起正常工作,例如:[pyclass]PyObjectAllocPyObjectWithFreeListimpl_classPyTypeInfo

#[pyfunction]
fn to_blocks(list: Vec<&Block>) -> Vec<i32>

您可以在官方文档中以总结的方式查看此解释。

FromPyObject由可以从 Python 对象引用中提取的各种类型实现。

于 2019-01-16T13:55:37.110 回答
0

看起来该pyfunction属性生成的代码要求返回类型实现该FromPyObject特征。虽然有一个全面的实现FromPyObject for Vec<T> where T: FromPyObject,但看起来为pyclass属性生成的代码不包括FromPyObject您的Block类型的实现。

由于除了几分钟之外我对 PyO3 不熟悉,我只是查看了它的 API 文档来验证这个答案,我不确定你如何最好地获得一个FromPyObject实现——也许有一个derive实现?

于 2019-01-16T10:00:33.820 回答
0

你在哪个版本的 PyO3 上?0.5.3你的代码在和上为我工作0.6.0-alpha.1

由于我无法对此进行测试,但我猜你需要返回一个PyResult

#[pyfunction]
fn to_blocks(list: Vec<i32>) -> PyResult<Vec<Block>>
于 2019-01-16T15:15:30.873 回答