3

我正在尝试将 Python 对象传递给 rust 并使用 Python 对象的字段执行操作。

Python:

class myclass(object):
    def __init__(self):
        self.a = 3

b = myclass()
print(b.a)
// 3

锈:

#[pyfn(m, "rust_obj")]
fn rust_obj_py(py: Python, x: PyObject) -> PyResult<PyObject> { 
    let y = x.clone_ref(py);
    y.a += 2;
    Ok(y)
}   

从 Python 调用时的预期结果是:

c = rust_obj(b)
print(c.a)
// 5

而是在编译时出现 Rust 错误:

error[E0609]: no field `a` on type `pyo3::PyObject`
   --> src\lib.rs:926:5
    |
926 |         y.a += 2;
    |           ^ unknown field

有没有办法在 rust 中列出对象字段和方法并操作字段?

4

1 回答 1

1

您正在调用clone_refy:

let y = x.clone_ref(py);

clone_ref返回另一个PyObject. 然后你在调用

y.a += 2;

并且编译器正确地告诉您“a类型 pyo3::PyObject 上没有字段”。因为PyObject不会直接在 Python 对象中公开您期望的字段(这样做很困难,因为 python 是动态类型的,而 rust 是静态类型的语言,所以 PyObject 的所有成员都必须在编译时知道) . 在这些情况下,文档有助于了解如何使用PyObject. 在那里你会看到你仍然可以访问a,但你必须通过getattr方法。为了做到这一点,+=我怀疑你最好通过API__iadd__显式调用 python 的方法。call_method

于 2020-04-20T23:52:30.410 回答