2

我正在使用最新版本的 pyo3(主分支),目前尚不清楚如何将一个类的实例存储Store在另一个类中,例如下面的示例。例如,下面的代码由两个类组成,Store并且MyClass会在一定程度上起作用。

use pyo3::prelude::*;

#[pyclass]
#[derive(Clone)]
struct Store {
    #[pyo3(get, set)]
    data: i32
}

#[pymethods]
impl Store {
    #[new]
    fn new(data: i32) -> Self {
        Store{ data }
    }
}

#[pyclass]
struct MyClass {
    #[pyo3(get, set)]
    store: Store,
}

#[pymethods]
impl MyClass {
    #[new]
    fn new(store: Store) -> Self {
        MyClass{ store }
    }
}

但是,当这些类在以下示例中的 Python 中使用时,断言会因为Store被克隆而失败。

import pyo3test as po3

mystore = po3.Store(7)
myobj = po3.MyClass(mystore)
assert(myobj.store is mystore)

如何修改 Rust 代码,使其保持对同一实例的引用Store?我认为它可能需要使用PyCell,但我不确定。

谢谢!

4

1 回答 1

5

如果您想在MyClassPythonstore中使用相同的对象,则必须包含Py,即:

#[pyclass]
struct MyClass {
    #[pyo3(get, set)]
    store: Py<Store>,
}

#[pymethods]
impl MyClass {
    #[new]
    fn new(store: Py<Store>) -> Self {
        MyClass { store }
    }
}

通过这些更改,您的断言对我来说通过了,并且两者都Store住在同一个地址:

>>> mystore = po3.Store(7)
>>> myobj = po3.MyClass(mystore)
>>> assert(myobj.store is mystore)
>>> mystore
  <Store at 0x7f3a726bc590>
>>> myobj.store
  <Store at 0x7f3a726bc590>
于 2021-05-26T22:12:08.900 回答