Вектор пользовательской структуры в PyO3
Я новичок в Rust и PyO3 (из Python), так что это может быть очевидно для более опытных людей.
Я объявил структуру Pyclass в PyO3.
#[pyclass]
struct Block {
start: i32,
stop: i32,
}
Тогда я использую 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>`
Как мне это решить?
РЕДАКТИРОВАТЬ: Caio прав. Я сделал ошибку в отслеживании ошибки. Ранее я написал
Затем я использую Block в функции rust, которая берет вектор int и выводит вектор Block (подпись ниже)
#[pyfunction]
fn to_blocks(list: Vec<i32>) -> Vec<Block>
Но фактическая оскорбительная функция:
#[pyfunction]
fn from_blocks(block_list: Vec<Block>) -> Vec<i32>
Я обновил вопрос, чтобы сделать его более понятным.
3 ответа
FromPyObject
предназначен для использования типами, которые могут быть извлечены из мира Python. Вот почему я думаю, что вы пытались написать fn to_blocks(list: Vec<Block>) -> Vec<i32>
вместо fn to_blocks(list: Vec<i32>) -> Vec<Block>
, Если это так, давайте перейдем к цепочке реализации.
FromPyObject
имеет реализацию по умолчанию для любого &T, который реализует PyTryFrom и PyTryFrom
имеет реализацию по умолчанию для любого T, который реализует PyTypeInfo. [pyclass]
инвентарь PyObjectAlloc
или же PyObjectWithFreeList
в соответствии с impl_class
метод и обе черты имеют PyTypeInfo
черта связана. Следовательно, ваш класс / структура будет отлично работать со ссылками, например:
#[pyfunction]
fn to_blocks(list: Vec<&Block>) -> Vec<i32>
Вы можете увидеть в официальной документации это объяснение в кратком изложении.
FromPyObject
реализуется различными типами, которые могут быть извлечены из ссылки на объект Python.
На какой версии PyO3 вы работаете? Ваш код работает на меня 0.5.3
а также 0.6.0-alpha.1
,
Из-за этого я не могу проверить это, но я думаю, что вам нужно вернуть PyResult
:
#[pyfunction]
fn to_blocks(list: Vec<i32>) -> PyResult<Vec<Block>>
Похоже, pyfunction
атрибут генерирует код, который требует, чтобы возвращаемый тип реализовывал FromPyObject
черта характера. Пока есть полная реализация FromPyObject for Vec<T> where T: FromPyObject
похоже на код, сгенерированный для pyclass
атрибут не включает реализацию FromPyObject
для тебя Block
тип.
Поскольку я незнаком с PyO3, за исключением нескольких минут, которые я только посмотрел на его документацию API, чтобы подтвердить этот ответ, я не уверен, как вам лучше всего получить FromPyObject
реализация - возможно, есть derive
для этого?