PyO3 中自定义结构的向量
Vector of custom struct in PyO3
我是 Rust 和 PyO3 的新手(来自 Python)所以这对更有经验的人来说可能很明显。
我在 PyO3 中声明了一个 pyclass 结构。
#[pyclass]
struct Block {
start: i32,
stop: i32,
}
然后我在 rust 函数中使用 Block
,该函数采用 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>`
我该如何解决这个问题?
编辑:
卡约是对的。我在追溯错误时犯了一个错误。
之前写过
Then I use Block in a rust function that takes a vector of int and outputs a vector of Block (signature below)
#[pyfunction]
fn to_blocks(list: Vec<i32>) -> Vec<Block>
但实际有问题的功能是:
#[pyfunction]
fn from_blocks(block_list: Vec<Block>) -> Vec<i32>
我已经更新了问题以使其更清楚。
看起来 pyfunction
属性生成的代码要求 return 类型实现 FromPyObject
特征。虽然有 FromPyObject for Vec<T> where T: FromPyObject
的全面实施,但看起来为 pyclass
属性生成的代码不包括 Block
类型的 FromPyObject
的实施。
由于除了几分钟之外我不熟悉 PyO3,我只是看了它的 API 文档来验证这个答案,我不确定你如何最好地获得 FromPyObject
实现-- 也许它有一个 derive
?
FromPyObject
旨在供可以从 Python 世界中提取的类型使用。这就是为什么我认为您试图写 fn to_blocks(list: Vec<Block>) -> Vec<i32>
而不是 fn to_blocks(list: Vec<i32>) -> Vec<Block>
。如果是这样,让我们进入实施链。
FromPyObject
具有 any &T that implements PyTryFrom and PyTryFrom
has a default implementation for any T that implements PyTypeInfo. [pyclass]
implements PyObjectAlloc
or PyObjectWithFreeList
according to the impl_class
方法的默认实现,并且两个特征都具有 PyTypeInfo
特征边界。因此,您的 class/struct 可以很好地处理引用,例如:
#[pyfunction]
fn to_blocks(list: Vec<&Block>) -> Vec<i32>
你可以在官方文档中看到这个概括的解释。
FromPyObject
is implemented by various types that can be extracted
from a Python object reference.
您使用的是哪个版本的 PyO3?
你的代码在 0.5.3
和 0.6.0-alpha.1
.
上为我工作
因此我无法对此进行测试,但我猜你需要 return a PyResult
:
#[pyfunction]
fn to_blocks(list: Vec<i32>) -> PyResult<Vec<Block>>
我是 Rust 和 PyO3 的新手(来自 Python)所以这对更有经验的人来说可能很明显。
我在 PyO3 中声明了一个 pyclass 结构。
#[pyclass]
struct Block {
start: i32,
stop: i32,
}
然后我在 rust 函数中使用 Block
,该函数采用 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>`
我该如何解决这个问题?
编辑: 卡约是对的。我在追溯错误时犯了一个错误。 之前写过
Then I use Block in a rust function that takes a vector of int and outputs a vector of Block (signature below)
#[pyfunction]
fn to_blocks(list: Vec<i32>) -> Vec<Block>
但实际有问题的功能是:
#[pyfunction]
fn from_blocks(block_list: Vec<Block>) -> Vec<i32>
我已经更新了问题以使其更清楚。
看起来 pyfunction
属性生成的代码要求 return 类型实现 FromPyObject
特征。虽然有 FromPyObject for Vec<T> where T: FromPyObject
的全面实施,但看起来为 pyclass
属性生成的代码不包括 Block
类型的 FromPyObject
的实施。
由于除了几分钟之外我不熟悉 PyO3,我只是看了它的 API 文档来验证这个答案,我不确定你如何最好地获得 FromPyObject
实现-- 也许它有一个 derive
?
FromPyObject
旨在供可以从 Python 世界中提取的类型使用。这就是为什么我认为您试图写 fn to_blocks(list: Vec<Block>) -> Vec<i32>
而不是 fn to_blocks(list: Vec<i32>) -> Vec<Block>
。如果是这样,让我们进入实施链。
FromPyObject
具有 any &T that implements PyTryFrom and PyTryFrom
has a default implementation for any T that implements PyTypeInfo. [pyclass]
implements PyObjectAlloc
or PyObjectWithFreeList
according to the impl_class
方法的默认实现,并且两个特征都具有 PyTypeInfo
特征边界。因此,您的 class/struct 可以很好地处理引用,例如:
#[pyfunction]
fn to_blocks(list: Vec<&Block>) -> Vec<i32>
你可以在官方文档中看到这个概括的解释。
FromPyObject
is implemented by various types that can be extracted from a Python object reference.
您使用的是哪个版本的 PyO3?
你的代码在 0.5.3
和 0.6.0-alpha.1
.
因此我无法对此进行测试,但我猜你需要 return a PyResult
:
#[pyfunction]
fn to_blocks(list: Vec<i32>) -> PyResult<Vec<Block>>