使用 PyO3 在 Rust 中调用 Python 包 JioNLP 实现成语接龙

使用 PyO3 在 Rust 中调用 Python 包 JioNLP 实现成语接龙

Photos provided by Unsplash OR Pexels

引言

在现代软件开发中,跨语言调用变得越来越常见。Rust 作为一种高性能的系统编程语言,与 Python 这种灵活且功能强大的脚本语言结合使用,可以发挥各自的优势。在本教程中,我们将使用 Rust 和 PyO3 库来调用 Python 包 JioNLP,实现一个简单的成语接龙游戏。我们将详细介绍如何设置 Rust 项目、创建 Python 虚拟环境、安装所需的 Python 包,并在 Rust 中调用 Python 代码。

1. 创建 Rust 项目

首先,创建一个新的 Rust 项目:

cargo new idiom_solitaire
cd idiom_solitaire

2. 添加 PyO3 依赖

Cargo.toml 文件中添加 PyO3 依赖:

[dependencies]
pyo3 = { version = "0.22.2", features = ["extension-module"] }

3. 使用 pyenv 管理 Python 环境

为了确保 Python 环境的一致性和可管理性,我们推荐使用 pyenv 来管理多个 Python 版本和虚拟环境。

安装 pyenv

在 macOS 上,可以使用 Homebrew 安装 pyenv

brew install pyenv

在 Linux 上,可以使用以下命令安装 pyenv

curl https://pyenv.run | bash

安装 Python 版本

使用 pyenv 安装所需的 Python 版本:

pyenv install 3.12.6

创建虚拟环境

使用 pyenv 创建一个新的虚拟环境:

pyenv virtualenv 3.12.6 idiom_solitaire_env

激活虚拟环境

激活虚拟环境:

pyenv activate idiom_solitaire_env

安装 JioNLP

在激活的虚拟环境中,使用 pip 安装 JioNLP 包:

pip install jionlp

4. 编写 Rust 代码

src/main.rs 中编写 Rust 代码来调用 JioNLPidiom_solitaire 函数。以下是一个完整的示例:

use pyo3::prelude::*;
use pyo3::types::PyDict;
use std::env;

fn main() -> PyResult<()> {
    // 设置 Python 解释器路径
    let python_interpreter = "~/.pyenv/versions/idiom_solitaire_env/bin/python";  // 根据你的 pyenv 路径调整

    // 设置环境变量
    env::set_var("PYO3_PYTHON", python_interpreter);

    // 初始化 Python 解释器
    Python::with_gil(|py| {
        // 导入 JioNLP 模块
        let jio = PyModule::import_bound(py, "jionlp")?;

        // 获取 idiom_solitaire 函数
        let idiom_solitaire = jio.getattr("idiom_solitaire")?;

        // 输入初始成语
        let mut idiom = String::from("一心一意");

        // 设置参数
        let args = PyDict::new(py);
        args.set_item("same_pinyin", false)?;
        args.set_item("same_tone", true)?;

        // 进行成语接龙
        for n in 0..10 {
            // A 角色接龙
            idiom = idiom_solitaire
                .call1((idiom.clone(), args.clone()))?
                .extract()?;
            println!("A: {}", idiom);

            // B 角色接龙
            idiom = idiom_solitaire
                .call1((idiom.clone(), args.clone()))?
                .extract()?;
            println!("B: {}", idiom);
        }

        Ok(())
    })
}

5. 深入剖析

5.1 设置 Python 解释器路径

我们通过设置 PYO3_PYTHON 环境变量来指定 Python 解释器的路径。这确保了 PyO3 使用正确的虚拟环境中的 Python 解释器。

let python_interpreter = "~/.pyenv/versions/idiom_solitaire_env/bin/python";  // 根据你的 pyenv 路径调整

env::set_var("PYO3_PYTHON", python_interpreter);

5.2 初始化 Python 解释器

使用 Python::with_gil 来初始化 Python 解释器并获取全局解释器锁(GIL)。

Python::with_gil(|py| {
    // 代码逻辑
})

5.3 导入 Python 模块

我们使用 PyModule::import_bound 来导入 JioNLP 模块。注意,import_boundimport 的替代方法,适用于 PyO3 0.22.2 版本。

let jio = PyModule::import_bound(py, "jionlp")?;

5.4 获取 Python 函数

使用 getattr 方法从模块中获取 idiom_solitaire 函数。

let idiom_solitaire = jio.getattr("idiom_solitaire")?;

5.5 设置函数参数

我们使用 PyDict 来创建一个字典,用于传递函数参数。注意,args 变量不需要 mut 修饰。

let args = PyDict::new(py);
args.set_item("same_pinyin", false)?;
args.set_item("same_tone", true)?;

5.6 调用 Python 函数

使用 call1 方法调用 Python 函数,并传递参数。然后使用 extract 方法将返回值转换为 Rust 类型。

idiom = idiom_solitaire
    .call1((idiom.clone(), args.clone()))?
    .extract()?;

6. 运行项目

确保虚拟环境已激活,然后运行 Rust 项目:

cargo run

总结

通过本教程,你学会了如何在 Rust 中使用 PyO3 调用 Python 包 JioNLP 来实现成语接龙的功能。我们详细介绍了如何设置 Rust 项目、使用 pyenv 管理 Python 虚拟环境、安装所需的 Python 包,并在 Rust 中调用 Python 代码。希望这篇教程对你有所帮助!

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)