简体   繁体   中英

Fuction which returns data loaded with Pyo3 - cannot return value referencing temporary value

I am trying to implement method which uses Pyo3 loads numpy array .

use ndarray::{array, ArrayView, Ix2};
use numpy::PyArray2;
use pyo3::types::IntoPyDict;
use pyo3::{PyResult, Python};

pub fn load_2d_vec<'a>() -> ArrayView<'a, f32, Ix2> {
    //  let res: PyResult<ArrayView<'a, f32, Ix2>> = Python::with_gil::<FnOnce(Python<'a>), ArrayView<'a, f32, Ix2>>(|py| {  // did no helped
    let res: PyResult<ArrayView<'a, f32, Ix2>> = Python::with_gil(|py| {
        let np = py.import("numpy")?;
        let locals = [("np", np)].into_py_dict(py);

        let pyarray: &PyArray2<f32> = py
            .eval(r#"np.load("./test_file")"#, Some(locals), None)?
            .extract()?;

        let f = pyarray.readonly().as_array();
        // let f: ArrayView<'a, f32, Ix2> = pyarray.readonly().as_array(); // with defined type and lifetime

        Ok(f) // TODO - cannot return value referencing temporary value [E0515] returns a value referencing data owned by the current function
    });

    res.unwrap()
}

fn main() {
    let a = load_2d_vec();
    assert_eq!(a, array![[1.0, 2.0], [3.0, 4.0]]);
}

But compilation failed "cannot return value referencing temporary value". I tryied to pass 'a life time to Python::with_gil method but I failed. any ideas? Thanks a lot.

I found it out. Python::with_gil entities has own 'py lifetime. This means that pyarray lives only in with_gil block. So I am not able to return pyarray in load_2d_vec directly. Instead of it I have to make a new variable into which data from pyarray are copied.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM