gpt4 book ai didi

python - 编写等同于返回其输入对象的 Python 函数的 pyo3 函数

转载 作者:太空狗 更新时间:2023-10-29 22:20:44 24 4
gpt4 key购买 nike

我正在为我的库编写一个 Rust 后端,我需要在 pyo3 中实现与以下函数等效的功能:

def f(x):
return x

这应该返回与输入相同的对象,并且获取返回值的函数应该持有对输入的新引用。如果我在 C API 中编写它,我会把它写成:

PyObject * f(PyObject * x) {
Py_XINCREF(x);
return x;
}

PyO3 , 我发现导航 PyObject 之间的差异非常困惑, PyObjectRef , &PyObject , Py<PyObject> , Py<&PyObject> .

这个函数最简单的版本是:

extern crate pyo3;

use pyo3::prelude::*;

#[pyfunction]
pub fn f(_py: Python, x: &PyObject) -> PyResult<&PyObject> {
Ok(x)
}

除其他事项外,x 的生命周期和返回值不一样,而且我看不到 pyo3 的机会增加 x 的引用计数,事实上编译器似乎同意我的观点:

error[E0106]: missing lifetime specifier
--> src/lib.rs:4:49
|
4 | pub fn f(_py: Python, x: &PyObject) -> PyResult<&PyObject> {
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_py` or `x`

我可能有办法手动使用 _py 增加引用计数参数并使用生命周期注解让编译器满意,但我的印象是 pyo3打算使用对象生命周期管理引用计数自身

编写此函数的正确方法是什么?我应该尝试将它包装在 Py 中吗?容器?

最佳答案

PyObjecta simple wrapper around a raw pointer :

pub struct PyObject(*mut ffi::PyObject);

它有多个创建函数,每个函数对应于我们可能从 Python 获得的不同类型的指针。其中一些,例如 from_borrowed_ptr , 在传入的指针上调用 Py_INCREF

因此,似乎我们可以接受 PyObject,只要它是以“正确”的方式创建的。

如果我们 expand这段代码:

#[pyfunction]
pub fn example(_py: Python, x: PyObject) -> PyObject {
x
}

我们可以看到调用我们函数的这段代码:

let mut _iter = _output.iter();
::pyo3::ObjectProtocol::extract(_iter.next().unwrap().unwrap()).and_then(
|arg1| {
::pyo3::ReturnTypeIntoPyResult::return_type_into_py_result(example(
_py, arg1,
))
},
)

我们的论点是通过调用 ObjectProtocol::extract 创建的,它又调用 FromPyObject::extract。这是 implemented for PyObject通过调用 from_borrowed_ptr

因此,使用裸 PyObject 作为参数类型将正确地增加引用计数。

同样,当一个 PyObject 被放入 Rust 中时,它会自动 decrease the reference count .当它返回给 Python 时,ownership is transferred适本地更新引用计数取决于 Python 代码。


commit ed273982 完成的所有调查来自master分支,对应v0.5.0-alpha.1。

关于python - 编写等同于返回其输入对象的 Python 函数的 pyo3 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52538458/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com