You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于PyO3实现Python调用可接收Python函数作为参数的Rust函数

如何基于PyO3实现Python调用可接收Python函数作为参数的Rust函数

当然可以实现这种双向调用啦!我来一步步给你讲清楚怎么操作:

一、Rust端代码实现

首先我们要编写能接收Python函数参数并调用它的Rust代码,借助PyO3的PyFunction类型就能轻松实现:

use pyo3::prelude::*;
use pyo3::types::PyFunction;

// 标注这个函数可以被Python调用
#[pyfunction]
fn my_rust_function(a: usize, f: &PyFunction) -> PyResult<usize> {
    // 调用传入的Python函数,将a作为位置参数传递
    let py_result = f.call1((a,))?;
    // 将Python返回的对象转换为Rust的usize类型
    py_result.extract()
}

// 定义Python模块,导出我们的函数
#[pymodule]
fn rust_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(my_rust_function, m)?)?;
    Ok(())
}

关键细节解释:

  • &PyFunction:PyO3提供的类型,用来表示传入的Python函数对象
  • call1((a,)):调用Python函数的方法,call1接收一个元组作为位置参数,这里我们把a打包成单元素元组传递
  • extract():负责把Python的返回值(比如int)转换成Rust对应的类型,这个操作会返回PyResult,用?可以自动将错误转换为Python异常抛出

二、Python端调用代码

接下来就可以在Python里调用这个Rust函数了,完全符合你预期的写法:

import rust_module

def double(x):
    return 2*x

def main():
    # 调用Rust函数,传入数值3和我们定义的double函数
    result = rust_module.my_rust_function(3, double)
    print(result)  # 运行后会输出6

if __name__ == "__main__":
    main()

三、构建与运行

要让Python能导入Rust模块,推荐用maturin工具来构建:

  1. 先安装maturin:pip install maturin
  2. 进入你的Rust项目目录,执行maturin develop,它会自动编译Rust代码并安装到当前Python环境中
  3. 之后就能直接运行上面的Python代码啦

额外注意事项:

  • 如果需要处理关键字参数,可以使用call方法代替call1,比如f.call((), Some(py_keyword_dict))
  • 所有涉及Python对象的操作都需要持有GIL(全局解释器锁),不过#[pyfunction]标注的函数被Python调用时,会自动持有GIL,无需额外处理
  • 如果Python函数返回的类型和你要提取的Rust类型不匹配,extract()会抛出Python异常,方便你调试

备注:内容来源于stack exchange,提问作者Red Rapious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:48:09