从 0 到 1:我的第一个 Rust-Python 绑定库开发之旅

文摘   科技   2025-01-05 00:15   四川  

引言

随着 Rust 语言的不断发展,越来越多的开发者开始关注这门高性能且安全的系统级编程语言。作为一名 Python 开发者,如何将 Rust 的高性能特性与 Python 的易用性结合起来?本文将分享一个真实的案例 —— 开发 PoloDB(一个类 MongoDB 的数据库)的 Python 绑定库的全过程。

开发环境准备

要开发 Rust-Python 绑定,我们需要以下工具:

Python 侧

  • 包管理器:推荐使用 Poetry 或 UV
  • Maturin:用于构建和打包包含 Rust 代码的 Python 包

Rust 侧

  • Cargo:Rust 官方包管理器
  • PyO3:提供 Rust 和 Python 之间类型转换的库

项目结构

一个标准的 Rust-Python 绑定项目结构如下:

polodb-python/
┣ polodb/
┃ ┣ __init__.py
┃ ┣ core.py
┃ ┗ version.py
┣ src/
┃ ┣ helper_type_translator.rs
┃ ┣ lib.rs
┃ ┗ py_database.rs
┣ tests/
┃ ┣ conftest.py
┃ ┗ test_database.py
┣ Cargo.toml
┣ pyproject.toml

核心实现示例

1. 在 Rust 中定义 Python 类和方法

下面是一个简单的示例,展示如何在 Rust 中定义可供 Python 使用的类和方法:

use pyo3::prelude::*;

// 定义一个简单的 Python 类
#[pyclass]
struct Greeting {
    name: String,
}

#[pymethods]
impl Greeting {
    // 构造函数
    #[new]
    fn new(name: String) -> Self {
        Greeting { name }
    }

    // 实例方法
    fn hello(&self) -> PyResult<String> {
        Ok(format!("你好,{}!"self.name))
    }
}

// 定义 Python 模块
#[pymodule]
fn greeting_module(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_class::<Greeting>()?;
    Ok(())
}

2. 复杂类型转换示例

在处理复杂类型时,需要特别注意 Python GIL(全局解释器锁)的使用:

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

#[pyclass]
pub struct PyCollection {
    // 使用 Arc 实现线程安全的共享所有权
    inner: Arc<Collection<Document>>,
}

#[pymethods]
impl PyCollection {
    // 插入一条文档
    pub fn insert_one(&self, doc: Py<PyDict>) -> PyResult<PyObject> {
        // 获取 Python GIL
        Python::with_gil(|py| {
            // 将 Python 字典转换为 BSON 文档
            let bson_doc: Document = convert_py_obj_to_document(&doc.into_ref(py))?;
            
            // 执行插入操作
            match self.inner.insert_one(bson_doc) {
                Ok(result) => {
                    // 将结果转换回 Python 对象
                    let py_result = bson_to_py_obj(py, &result.inserted_id)?;
                    Ok(py_result)
                }
                Err(e) => Err(PyRuntimeError::new_err(e.to_string()))
            }
        })
    }
}

使用方式

在 Python 中使用上述绑定库:

from rust_polodb import PyDatabase

# 创建数据库实例
db = PyDatabase("test.db")

# 获取集合
collection = db.collection("users")

# 插入文档
result = collection.insert_one({
    "name""张三",
    "age"25,
    "email""zhangsan@example.com"
})

print(f"插入的文档 ID:{result.inserted_id}")

总结

开发 Rust-Python 绑定库是一个很好的学习 Rust 的途径,它不仅能够帮助我们理解两种语言的特点,还能够实现性能和易用性的完美结合。通过本文的示例,我们了解了:

  1. 如何搭建 Rust-Python 绑定项目的基本结构
  2. 如何使用 PyO3 在 Rust 中定义 Python 类和方法
  3. 如何处理复杂类型的转换
  4. 如何正确使用 Python GIL

这些知识将帮助你开发出高性能且易于使用的 Python 扩展库。

参考文章

  1. How I published my 1st Rust-Python binding package:https://hamza-senhajirhazi.medium.com/how-i-published-my-1st-rust-python-binding-package-cb44bc4e2e94
  2. PyO3 官方文档:https://pyo3.rs/
  3. Rust 程序设计语言:https://doc.rust-lang.org/book/

书籍推荐

各位 Rust 爱好者,今天为大家介绍一本《Programming Rust: Fast, Safe Systems Development》(第二版) 是由 Jim Blandy、Jason Orendorff 和 Leonora Tindall 合著的 Rust 编程指南。本书深入探讨了 Rust 语言在系统编程中的应用,着重介绍如何利用 Rust 的独特特性来平衡性能和安全性。书中涵盖了 Rust 的基础数据类型、所有权和借用概念、特征和泛型、并发编程、闭包、迭代器以及异步编程等核心内容。这本更新版基于 Rust 2021 版本,为系统程序员提供了全面而实用的 Rust 编程指导。

  1.  Rust:横扫 C/C++/Go 的性能之王?

  2.  从 Rust 开发者视角看 C++:优缺点大揭秘

  3.  Rust vs Zig:新兴系统编程语言之争

数据科学研习社
带你走进数据科学的世界🚀
 最新文章