编程学习网 > 编程语言 > Python > 玩转 Rust 与 Python 互操作:pyo3 + maturin 实践指南!
2024
04-07

玩转 Rust 与 Python 互操作:pyo3 + maturin 实践指南!

Python 是当今最流行的编程语言之一,拥有丰富的生态系统和广泛的应用领域。但在某些场景下,Python 的性能可能无法满足要求。这时,我们可以考虑使用 Rust 编程语言来编写性能关键的部分,并与 Python 进行互操作。本文将介绍如何使用 pyo3 和 maturin 这两个强大的工具来实现 Rust 与 Python 的无缝整合。


创作背景
最近,我在开发一个 Python 项目时遇到了性能瓶颈。经过分析,发现某些计算密集型的任务拖慢了整个程序的速度。为了解决这个问题,我决定尝试使用 Rust 来优化这部分代码。经过一番调研,我发现了 pyo3 和 maturin 这两个优秀的工具,它们可以帮助我轻松地实现 Rust 与 Python 的互操作。因此,我决定分享我的学习心得,希望能对有类似需求的读者有所帮助。

主要特性
pyo3
pyo3 是一个用于 Rust 与 Python 互操作的库,它提供了以下主要特性:

在 Rust 中调用 Python 代码
在 Python 中调用 Rust 代码
在 Rust 中定义 Python 类和函数
在 Rust 中操作 Python 对象
自动处理 Python 的引用计数和垃圾回收
pyo3 的当前版本为 0.21.0,可以在 Cargo.toml 中添加以下依赖来使用它:

[dependencies]
pyo3 = "0.21.0"
maturin
maturin 是一个用于打包和发布包含 pyo3、rust-cpython 或 cffi 绑定的 Rust 代码为 Python 包的工具。它简化了构建和发布过程,提供了以下主要特性:

自动生成 Python 包的元数据和构建脚本
支持交叉编译和条件编译
自动处理 Python 版本和平台的兼容性
支持发布到 PyPI 和其他私有仓库
快速上手
下面,我们将通过一个简单的示例来演示如何使用 pyo3 和 maturin 实现 Rust 与 Python 的互操作。

步骤 1:创建 Rust 项目
首先,使用 cargo new 命令创建一个新的 Rust 项目:

cargo new rust-py-example --lib
cd rust-py-example
步骤 2:添加 pyo3 依赖
在 Cargo.toml 文件中添加 pyo3 依赖:

[package]
name = "rust-py-example"
version = "0.1.0"
edition = "2021"

[lib]
name = "rust_py_example"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.21.0", features = ["extension-module"] }
步骤 3:编写 Rust 代码
在 src/lib.rs 文件中编写 Rust 代码:

use pyo3::prelude::*;

/// 计算斐波那契数列的第 n 项
#[pyfunction]
fn fib(n: usize) -> PyResult<u64> {
    if n <= 1 {
        Ok(n as u64)
    } else {
        let mut a = 0u64;
        let mut b = 1u64;
        for _ in 2..=n {
            let c = a + b;
            a = b;
            b = c;
        }
        Ok(b)
    }
}

/// 定义 Python 模块
#[pymodule]
fn rust_py_example(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(fib, m)?)?;
    Ok(())
}
这段代码定义了一个 fib 函数,用于计算斐波那契数列的第 n 项。它使用 #[pyfunction] 属性将其标记为 Python 函数。然后,在 #[pymodule] 中将这个函数添加到 Python 模块中。

注意在 pyo3 的 0.21.0 版本中只需要在 rust_py_example 函数中传入一个参数即可:m: &Bound<'_, PyModule>,这个写法与之前的版本有较大的差别!

步骤 4:构建和安装 Python 包
此处假设有系统全局安装的 Python,如果是利用 conda 配置的虚拟环境中使用,则需要配置相关的 PYO3_PYTHON 环境变量来指定 Python 解释器的路径

这里给大家提供一个基于 VSCode 的 settings.json 配置:

{
    // 为 Rust Analyzer 语言服务器指定环境变量,影响语言服务器进程
    "rust-analyzer.server.extraEnv": {
        // 设定 PYO3_PYTHON 环境变量,指定 Rust 中使用 PyO3 时的 Python 解释器路径
        "PYO3_PYTHON": "C:\\Users\\albert\\.conda\\envs\\rshare\\python.exe"
    },
    // 为通过 Rust Analyzer 运行或调试的可执行文件指定额外的环境变量
    "rust-analyzer.runnables.extraEnv": {
        // 设定 PYO3_PYTHON 环境变量,用于运行或调试时确定 Python 解释器路径
        "PYO3_PYTHON": "C:\\Users\\albert\\.conda\\envs\\rshare\\python.exe"
    },
    // 定义 VS Code 集成终端中的自定义终端配置
    "terminal.integrated.profiles.windows": {
        // 创建一个名为 "Conda Powershell" 的终端配置
        "Conda Powershell": {
            "path": "powershell.exe",
            // 配置参数以启动并激活指定的 Conda 环境,然后继续使用 PowerShell
            "args": ["-NoExit", "-Command", "& cmd.exe /c 'C:\\ProgramData\\Miniconda3\\Scripts\\activate.bat C:\\Users\\albert\\.conda\\envs\\rshare && powershell'"]
        }
    },
    // 设置 "Conda Powershell" 为集成终端的默认配置
    "terminal.integrated.defaultProfile.windows": "Conda Powershell",
    "liveServer.settings.port": 5532
}
使用 maturin 构建和安装 Python 包:

pip install maturin
maturin develop
这将在当前环境中安装名为 rust_py_example 的 Python 包。

步骤 5:在 Python 中使用 Rust 代码
现在,我们可以在 Python 中使用 Rust 编写的函数了:

import rust_py_example

print(rust_py_example.fib(10))  # 输出:55
这个示例展示了如何在 Python 中调用 Rust 编写的高性能函数,实现了 Rust 与 Python 的互操作。

总结

通过使用 pyo3 和 maturin,我们可以轻松地实现 Rust 与 Python 的互操作,将 Rust 的高性能特性引入 Python 项目中。这为优化 Python 程序的性能提供了一种可行的方案。希望本文能够帮助读者了解和掌握这两个强大的工具,提升项目的性能和开发效率。

以上就是玩转 Rust 与 Python 互操作:pyo3 + maturin 实践指南!的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取