Передача объекта Python в Rust
Я пытаюсь передать объект Python в ржавчину и выполнить операции, используя поля объекта 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
Есть ли способ перечислить поля и методы объекта в ржавчине и управлять полями?
1 ответ
Вы звоните clone_ref
по y:
let y = x.clone_ref(py);
clone_ref
возвращает другой PyObject
. Тогда вы вызываете
y.a += 2;
И компилятор правильно говорит вам "нет поля a
по типу pyo3::PyObject". Потому что PyObject
не раскрывает поля, которые вы ожидаете от объекта Python напрямую (это было бы сложно сделать, поскольку python динамически типизирован, тогда как rust - статически типизированный язык, поэтому все члены PyObject должны быть известны во время компиляции). В этих случаях документация полезна, чтобы узнать, как использовать PyObject
. Там вы увидите, что у вас все еще есть доступa
, но вы должны пройти через getattr
метод. Чтобы сделать+=
Я подозреваю, что лучше всего назвать python __iadd__
явно через call_method
API.