我有一个预导入的模块,我正在使用 python gil 调用一个方法,如下所示。
Python::with_gil(|py| {
let res = module.call_method1(py, "my_method", (arg1, arg2))?;
})
这会返回 rust 对象 PyObject,但是返回的是一个 python list
。我想迭代这个列表,将内部转换为我可以在 Rust 中使用的东西(它是 Numpy 数组的 python 列表,我正在使用 numpy/ndarray 板条箱)。
我对如何迭代这个有点困惑。如果我尝试将 cast_as
转换为 PyList
,我会收到警告:UnsafeCell无法在线程之间安全地共享
。看来extract
也不起作用。
如何迭代这个 PyObject?谢谢。
编辑:根据要求添加更多详细信息
如果您使用的是 python 打字系统,则 python 返回的值是一个 List[numpy.ndarray]
。由于每个 numpy 数组的长度可能不同,我不能将其全部转换为 python 中的 numpy 数组并传递它。示例输出如下:
[array([214.17725372, 192.78236675, 354.27965546, 389.84558392,
0.99999297])]
我在 Rust 中尝试过的内容:
-
let pylist = res.cast_as::(py)?;
无法编译:UnsafeCell;无法在线程之间安全地共享
。
-
let pylist = res.extract::(py)?;
无法编译:未针对“PyList”实现特征“PyClass”
。请注意,我在顶部有use pyo3::prelude::*;
。
-
let pyany = res.extract::>>(py)?;
无法编译:特征绑定 'Vec>: pyo3::FromPyObject<'_>'不满意
。这个 PyArray 来自 numpy
板条箱。
I have a pre-imported module that I'm calling a method with python gil, something like the following.
Python::with_gil(|py| {
let res = module.call_method1(py, "my_method", (arg1, arg2))?;
})
This returns the rust object PyObject, however what this returns is a python list
. I want to iterate over this list to convert the internals into something I can use in Rust (it's a python list of Numpy arrays, I'm using the numpy/ndarray crates).
I'm a little confused as to how I'm meant to iterate over this. If I try cast_as
to a PyList
, I get the warning: UnsafeCell<PyObject> cannot be shared between threads safely
. It seems extract
does not work either.
How do I iterate over this PyObject? Thanks.
Edit: Adding further details as requested
The returned value from python is a List[numpy.ndarray]
if you are using the python Typing system. As the lengths of each numpy array could be different, I cannot just convert it all into a numpy array in python and pass it through. An example output is below:
[array([214.17725372, 192.78236675, 354.27965546, 389.84558392,
0.99999297])]
What I've tried in Rust:
-
let pylist = res.cast_as::<PyList>(py)?;
Fails to compile with: UnsafeCell<PyObject> cannot be shared between threads safely
.
-
let pylist = res.extract::<PyList>(py)?;
Fails to compile with: the trait 'PyClass' is not implemented for 'PyList'
. Please note I have use pyo3::prelude::*;
at the top.
-
let pyany = res.extract::<Vec<PyArray1<f64>>>(py)?;
Fails to compile with: the trait bound 'Vec<PyArray<f64, Dim<[usize; 1]>>>: pyo3::FromPyObject<'_>' is not satisfied
. This PyArray is from the numpy
crate.
发布评论
评论(1)
我看到您返回了带有
dtype=float
的numpy
数组列表。如果您愿意使用其他依赖项,可以使用 rust-numpy 来映射numpy
数组到ndarrays
。ndarrays 有一个 .to_vec() 方法来转换为标准 Rust 容器。
在您的情况下,您可以执行以下操作(未经测试):
可以找到 Python 和 Rust 类型之间的映射
I see that you returning a list of
numpy
arrays withdtype=float
. If you are open to using another dependency, there is rust-numpy which lets you mapnumpy
arrays tondarrays
in Rust.ndarrays
have a.to_vec()
method to convert to standard Rust containers.In your case you could do the following (this is not tested):
Mappings between Python and Rust types can be found here. You can then use the
res
to do further computations.