如何解决如何在 Rust PyO3
当我们编写 vanilla rust 并且必须将异步函数作为参数传递给另一个函数时,我们执行以下操作:
pub f<F,'a>(
test: &dyn Fn(&'a mut String,String,Tcpstream) -> F,) where
F: Future<Output = ()> + 'a,
但是,当我对 #![pyfunction]
执行相同操作并希望获得异步 python 函数时,我收到了错误消息。
e.g async def fn():
....
在阅读 PyO3 的文档时,我发现我可以包含 PyAny
作为参数。
但是,关于实现以下功能:
pub fn start_server(test: PyAny) {
test.call0();
}
我收到以下错误。
[rustc E0277] [E] the trait bound `pyo3::PyAny: pyo3::FromPyObject<'_>` is not satisfied
expected an implementor of trait `pyo3::FromPyObject<'_>`
note: required because of the requirements on the impl of `pyo3::FromPyObject<'_>` for `pyo3::PyAny`
如何在我的代码中实现这一点。如果这是不可能的,我会理解,如果是这种情况,我会请求您向我推荐一个替代方案。
更新:
我找到了一个替代方法,我创建一个空结构并按以下方式调用该方法。但如果我能在不创建空结构的情况下完成,我会非常感激。
#[pymethods]
impl Server {
#[new]
fn new() -> Self {
Self {}
}
fn start(mut self_: PyRefMut<Self>,test: &PyAny) {
test.call0();
}
}
RuntimeWarning: coroutine
s.start(h)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
解决方法
您的函数需要引用,即 &PyAny
。 PyAny
作为拥有的值未实现 FromPyObject
,这就是您收到错误的原因。
// lib.rs
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
#[pyfunction]
fn foo(x: &PyAny) -> PyResult<&PyAny> {
x.call0()
}
#[pymodule]
fn async_pyo3(py: Python,m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(foo,m)?).unwrap();
Ok(())
}
import async_pyo3
async def bar():
return "foo"
awaitable = async_pyo3.foo(bar) # <coroutine object bar at 0x7f8f6aa01340>
print(await awaitable) # "foo"
因此,将其移至 Server
上的方法的修复很可能不是修复,而只是巧合,因为您将 test
更改为 &PyAny
。
有 a whole section in the PyO3 documentation 关于集成 Python 和 Rust async / await
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。