Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Rust PyO3中作为参数传递异步函数_Python_Asynchronous_Rust_Async Await_Pyo3 - Fatal编程技术网

Python 如何在Rust PyO3中作为参数传递异步函数

Python 如何在Rust PyO3中作为参数传递异步函数,python,asynchronous,rust,async-await,pyo3,Python,Asynchronous,Rust,Async Await,Pyo3,当我们编写一个异步函数并将其作为参数传递给另一个函数时,我们会执行以下操作: pub f<F,'a>( test: &dyn Fn(&'a mut String, String, String, TcpStream) -> F, ) where F: Future<Output = ()> + 'a, 在阅读PyO3的文档时,我发现我可以将PyAny作为参数 但是,在实现以下功能时: pub fn start_server(test

当我们编写一个异步函数并将其作为参数传递给另一个函数时,我们会执行以下操作:

pub f<F,'a>(
    test: &dyn Fn(&'a mut String, String, String, TcpStream) -> F,
) where
    F: Future<Output = ()> + 'a,
在阅读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`

您的函数需要引用,即
&PyAny
PyAny
作为一个拥有的值不会实现pyobject中的
,这就是为什么会出现错误

// 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(())
}

//lib.rs
使用pyo3::前奏::*;
使用pyo3::wrap_py函数;
#[pyfunction]
fn foo(x:&PyAny)->PyResult{
x、 call0()
}
#[pymodule]
fn async_pyo3(py:Python,m:&PyModule)->PyResult{
m、 add_函数(wrap_pyfunction!(foo,m)?).unwrap();
好(())
}
导入异步\u pyo3
异步定义栏():
返回“foo”
waitiable=async_pyo3.foo(bar)#
打印(等待等待)#“foo”
因此,将其移动到
服务器上的方法的修复很可能不是修复,而是巧合,因为您将
test
更改为
&PyAny


还有关于集成Python和Rust async/await的问题,您必须提供更多的信息和确切的错误,否则人们将无法提供帮助。请看这个关于最小可复制示例的解释:@sebpuetz,我做了一些补充。如果需要我提供更多信息,请务必告诉我。即使将其更改为&PyAny也无法修复它,并且发出了相同的错误。它在本地对我有效,我将编辑我的答案以包含完整的Python&Rust代码。
#[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
// 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"